Putting It All Back Together

Throughout all the data analysis we’ve done, the datasets have become more fragmented - lexical recall, gist, and eye tracking datasets. I want to put them all together in one whole dataset again so we can perform some analyses more efficiently (particularly correlations). The only thing I need to remember is we’ll have a new column called eye_exclude and if it is set to TRUE it means we can’t include that row in any analysis relating to eye gaze (usually because that trial was less than 25% looking).

# Libraries
library(tidyverse)
library(lme4)
library(lmerTest)
library(scales)
library(viridis)
library(agricolae) 
library(GGally)
library(ez)
# Load lex and eye data
cleanlexdata <- read_csv("cleandata.csv") %>%
  select(-(forehead:total))
cleaneyedata <- read_csv("cleanpercentdata.csv") %>%
  spread(aoi,percent) %>%
  add_column(eye_exclude = FALSE)
# What rows were removed from the eye data back in 03eyegaze? Let's add back in
# With a new column - eye_exclude
removed <- anti_join(cleanlexdata, cleaneyedata) %>%
  add_column(eye_exclude = TRUE)
eyelexdata <- bind_rows(cleaneyedata, removed)
# Load gist data
gist <- read_csv('gist_indiv.csv', col_types = cols(
  participant = col_character(),
  gist.fw1 = col_integer(),
  gist.rv2 = col_integer(),
  gist.fw3 = col_integer(),
  gist.rv4 = col_integer()
)) %>%
  gather(video, gist, gist.fw1:gist.rv4) %>%
  mutate(video = str_sub(video,6,8))
# Presto, our full reunified dataset - 'fulldata'
# But I want to remove columns I don't want anymore and will recalculate later
fulldata <- left_join(eyelexdata, gist) %>%
  select(-moutheye, -facechest, -face, -chest)

Group Changes and Participant Tables

We have some changes to make to the groups. First, fix Josh as learning ASL when he was 6. Next, drop the DeafNative Group and reclassify all who learned ASL < 3.9 as DeafEarly and ASL => 4.0 as DeafLate.

# Change Josh's AoASL to 6
fulldata <- fulldata %>%
  mutate(aoasl = as.double(aoasl)) %>%
  mutate(aoasl = case_when(
    participant == "Josh" ~ 6,
    TRUE ~ aoasl
  ))
# Reclassify Groups
fulldata <- fulldata %>%
  mutate(maingroup = case_when(
    hearing == "Deaf" & aoasl < 4 ~ "DeafEarly",
    hearing == "Deaf" & aoasl >= 4 ~ "DeafLate",
    maingroup == "HearingLateASL" ~ "HearingLate",
    maingroup == "HearingNoviceASL" ~ "HearingNovice"
  ))
# Create Participant Demographics Table
participant_info <- fulldata %>%
  select(-(acc:gist)) %>%
  select(-(video:direction)) %>%
  distinct() %>% 
  group_by(maingroup) %>%
  summarise(n = n(),
            age_mean = mean(age),
            age_sd = sd(age),
            aoasl_mean = mean(aoasl),
            aoasl_sd = sd(aoasl),
            signyrs_mean = mean(signyrs),
            signyrs_sd = sd(signyrs),
            selfrate_mean = mean(selfrate),
            selfrate_sd = sd(selfrate)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>%
  mutate(age = paste(age_mean, "±", age_sd, sep = " "),
         aoasl = paste(aoasl_mean, "±", aoasl_sd, sep = " "),
         signyrs = paste(signyrs_mean, "±", signyrs_sd, sep = " "),
         selfrate = paste(selfrate_mean, "±", selfrate_sd, sep = " ")) %>%
  select(-(age_mean:selfrate_sd))
participant_info
write_csv(fulldata, "finaldataset.csv")
data_lowaoi <- fulldata %>% select(participant, story, belly:upperchest) %>% select(-eyes, -mouth, -chin) %>% gather(aoi, percent, belly:upperchest)
data_lowaoi$percent[is.na(data_lowaoi$percent)] <- 0
mean(data_lowaoi$percent, na.rm=TRUE)
[1] 0.007421356
sd(data_lowaoi$percent, na.rm=TRUE)
[1] 0.02793204

Participant ANOVAs

Below are the ANOVA outputs for participant demographics, and LSDs for each.

Participants’ age

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   1810   603.3   14.29 8.75e-07 ***
Residuals   48   2026    42.2                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ AoASL

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3 2553.9   851.3   89.98 <2e-16 ***
Residuals   48  454.1     9.5                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ Sign Yrs

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   7032  2344.1   59.37 3.52e-16 ***
Residuals   48   1895    39.5                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ Self-Rating

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3  30.71  10.237   72.37 <2e-16 ***
Residuals   48   6.79   0.141                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Gist & Lexical Recall Data

Tables & Charts

Let’s generate a table for lexical recall and gist for forward vs. reversed stories.

lexgist_info <- fulldata %>%
  group_by(maingroup, direction) %>%
  summarise(lex_mean = mean(acc, na.rm = TRUE),
            lex_sd = sd(acc, na.rm = TRUE),
            gist_mean = mean(gist),
            gist_sd = sd(gist)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>% 
  mutate(lex = paste(lex_mean, "±", lex_sd, sep = " "),
         gist = paste(gist_mean, "±", gist_sd, sep = " ")) %>%
  select(-(lex_mean:gist_sd)) %>%
  gather(metric, value, lex:gist) %>%
  unite("metric", c(metric, direction), sep = "_") %>%
  spread(metric, value) %>%
  print()

And then bar charts too after that with error bars.

# Gist bar chart
gist_bar <- fulldata %>% select(participant, maingroup, direction, gist) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(gist = mean(gist)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(gist),
            sd = sd(gist),
            count = n(),
            se = sd/sqrt(count)) %>%
  ungroup() %>%
  mutate(maingroup = case_when(
    maingroup == "DeafEarly" ~ "Deaf Early",
    maingroup == "DeafLate" ~ "Deaf Late",
    maingroup == "HearingLate" ~ "Hearing Late",
    maingroup == "HearingNovice" ~ "Hearing Novice"
    ))
ggplot(gist_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Gist", x = "", y = "mean gist accuracy") +
  scale_y_continuous(labels = percent, limits = c(0,1)) + theme_bw()

# Lex bar chart
lex_bar <- fulldata %>% select(participant, maingroup, direction, acc) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(acc = mean(acc, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(acc, na.rm = TRUE),
            sd = sd(acc, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count)) %>%
  ungroup() %>%
  mutate(maingroup = case_when(
    maingroup == "DeafEarly" ~ "Deaf Early",
    maingroup == "DeafLate" ~ "Deaf Late",
    maingroup == "HearingLate" ~ "Hearing Late",
    maingroup == "HearingNovice" ~ "Hearing Novice"
    ))
ggplot(lex_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Lexical Recall", x = "", y = "mean lexical recall accuracy") +
  scale_y_continuous(labels = percent, limits = c(0,1)) +
  geom_hline(yintercept = .5, linetype = "dotted") +
  coord_cartesian(ylim = c(.5,1)) + theme_bw()

And let’s calculate the average reduction in score due to reversal first is lex recall, then gist.

reversal_lex <- fulldata %>%
  group_by(id, direction) %>%
  summarise(lex_mean = mean(acc, na.rm = TRUE)) %>%
  spread(direction, lex_mean) %>%
  group_by(id) %>%
  mutate(reversal = forward - reversed) %>%
  ungroup()
paste("lex mean", mean(reversal_lex$reversal))
[1] "lex mean 0.141570192307692"
paste("lex sd", sd(reversal_lex$reversal))
[1] "lex sd 0.102655144785552"
reversal_gist <- fulldata %>%
  group_by(id, direction) %>%
  summarise(gist_mean = mean(gist, na.rm = TRUE)) %>%
  spread(direction, gist_mean) %>%
  group_by(id) %>%
  mutate(reversal = forward - reversed) %>%
  ungroup()
paste("gist mean", mean(reversal_gist$reversal))
[1] "gist mean 0.451923076923077"
paste("gist sd", sd(reversal_gist$reversal))
[1] "gist sd 0.39925930667527"

ANOVA Plan

Next, we’re going to do ANOVAs. We’ll always do it in this order.

  1. ANOVA with factors MainGroup & Direction
  2. ANOVA with factor MainGroup, for Forward only
  3. ANOVA with factor MainGroup, for Reverse only

(I also ran ANCOVAs before but now have taken them out…they are below: (4) ANCOVA with factor Direction, and covariate AoASL and Age, (5) Regression with variables AoASL and Age, for Forward only, (6) Regression with variables AoASL and Age, for Reverse only.)

I did not include Age as a covariate in the first 3 ANOVAs because they did not add to or change the model in any significant way.

Gist ANOVAs

  1. ANOVA with factors MainGroup & Direction.
# First let's make the participant-level dataset with which we'll do our ANCOVAs. 
participant_data <- fulldata %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         acc = mean(acc, na.rm = TRUE)) %>%
  ungroup() %>%
  select(id, participant, hearing, maingroup, direction, age, aoasl, acc, gist) %>%
  distinct() %>%
  mutate(id = factor(id),
         participant = factor(participant),
         hearing = factor(hearing),
         maingroup = factor(maingroup),
         direction = factor(direction))
# # Gist ANOVA 1
# gist_aov1 <- aov(gist ~ maingroup * direction, data = participant_data)
# summary(gist_aov1)
# gist_lsd1 <- LSD.test(gist_aov1, "maingroup", group = FALSE)
# gist_lsd1$comparison
# Gist EZ ANOVA
ezANOVA(
  data = participant_data,
  dv = gist,
  wid = id,
  within = direction,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only. In the code is a Kruskal-Wallis test. And Chi-Sq too.
# # Gist ANOVA 2
# gist_aov2 <- aov(gist ~ maingroup, data = filter(participant_data, direction == "forward"))
# summary(gist_aov2)
# gist_lsd2 <- LSD.test(gist_aov2, "maingroup", group = FALSE)
# gist_lsd2$comparison
ezANOVA(
  data = filter(participant_data, direction == "forward"),
  dv = gist,
  wid = id,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
# # KW Non-parametric test (like one-way ANOVA)
# kruskal.test(gist ~ maingroup, data = as.matrix(filter(participant_data, direction == "forward")))
# 
# # Chi Sq
# gist_chisq_fw <- participant_data %>%
#   ungroup() %>%
#   filter(direction == "forward") %>%
#   select(maingroup, gist) %>%
#   group_by(maingroup, gist) %>%
#   summarise(count = n()) %>%
#   spread(gist, count) %>%
#   rename(none = "0",
#          one = "0.5",
#          both = "1")
# 
# gist_chisq_fw[is.na(gist_chisq_fw)] <- 0L
# gist_chisq_fw <- cbind(gist_chisq_fw[,"none"], gist_chisq_fw[,"one"], gist_chisq_fw[,"both"])
# chisq.test(gist_chisq_fw)
  1. ANOVA with factor MainGroup, for Reverse only. In the code is a Kruskal-Wallis test. And Chi-Sq too.
# # Gist ANOVA 3
# gist_aov3 <- aov(gist ~ maingroup, data = filter(participant_data, direction == "reversed"))
# summary(gist_aov3)
# gist_lsd3 <- LSD.test(gist_aov3, "maingroup", group = FALSE)
# gist_lsd3$comparison 
ezANOVA(
  data = filter(participant_data, direction == "reversed"),
  dv = gist,
  wid = id,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
# # KW Non-parametric test (like one-way ANOVA)
# kruskal.test(gist ~ maingroup, data = as.matrix(filter(participant_data, direction == "reversed")))
# 
# # Chi Sq
# gist_chisq_rv <- participant_data %>%
#   ungroup() %>%
#   filter(direction == "reversed") %>%
#   select(maingroup, gist) %>%
#   group_by(maingroup, gist) %>%
#   summarise(count = n()) %>%
#   spread(gist, count) %>%
#   rename(none = "0",
#          one = "0.5",
#          both = "1")
# 
# gist_chisq_rv[is.na(gist_chisq_rv)] <- 0L
# gist_chisq_rv <- cbind(gist_chisq_rv[,"none"], gist_chisq_rv[,"one"], gist_chisq_rv[,"both"])
# chisq.test(gist_chisq_rv)

Lexical Recall ANOVAs

  1. ANOVA with factors MainGroup & Direction.
# # Lexical Recall ANOVA 1
# acc_aov1 <- aov(acc ~ maingroup * direction, data = participant_data)
# summary(acc_aov1)
# acc_lsd1 <- LSD.test(acc_aov1, "maingroup", group = FALSE)
# acc_lsd1$comparison
ezANOVA(
  data = participant_data,
  dv = acc,
  wid = id,
  within = direction,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only.
# # Lexical Recall ANOVA 2
# acc_aov2 <- aov(acc ~ maingroup, data = filter(participant_data, direction == "forward"))
# summary(acc_aov2)
# acc_lsd2 <- LSD.test(acc_aov2, "maingroup", group = FALSE)
# acc_lsd2$comparison
ezANOVA(
  data = filter(participant_data, direction == "forward"),
  dv = acc,
  wid = id,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Reverse only.
# # Lexical Recall ANOVA 3
# acc_aov3 <- aov(acc ~ maingroup, data = filter(participant_data, direction == "reversed"))
# summary(acc_aov3)
# acc_lsd3 <- LSD.test(acc_aov3, "maingroup", group = FALSE)
# acc_lsd3$comparison
ezANOVA(
  data = filter(participant_data, direction == "reversed"),
  dv = acc,
  wid = id,
  between = maingroup,
  type = 3
)["ANOVA"]
Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA

AoA Correlations

Next, we want to look at correlations between AoA and Gist, and betwen AoA and Lexical Recall. Rain asked for forward and reversed separately (1) deaf only, (2) hearing only, and (3) both. Let’s make it work.

# Let's make participant-level data, and have forward/reversed in separate columns
lexgist_data <- fulldata %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         lex = mean(acc, na.rm = TRUE)) %>%
  ungroup() %>%
  select(maingroup, participant, hearing, direction, aoasl, signyrs, age, gist, lex) %>%
  distinct() %>%
  gather(metric, value, gist:lex) %>%
  unite(metricvalue, c(metric, direction), sep = "_") %>%
  spread(metricvalue, value) %>%
  select(-participant, -maingroup)
lexgist_deaf <- lexgist_data %>% filter(hearing == "Deaf") %>% select(-hearing)
lexgist_hearing <- lexgist_data %>% filter(hearing == "Hearing") %>% select(-hearing)
lexgist_all <- lexgist_data %>% select(-hearing)
# Load awesome function to make correlation tables with stars for significance
# From: https://myowelt.blogspot.co.uk/2008/04/beautiful-correlation-tables-in-r.html
corstarsl <- function(x){ 
require(Hmisc) 
x <- as.matrix(x) 
R <- Hmisc::rcorr(x)$r 
p <- Hmisc::rcorr(x)$P 
## define notions for significance levels; spacing is important.
mystars <- ifelse(p < .001, "***", ifelse(p < .01, "** ", ifelse(p < .05, "* ", " ")))
## trunctuate the matrix that holds the correlations to two decimal
R <- format(round(cbind(rep(-1.11, ncol(x)), R), 2))[,-1] 
## build a new matrix that includes the correlations with their apropriate stars 
Rnew <- matrix(paste(R, mystars, sep=""), ncol=ncol(x)) 
diag(Rnew) <- paste(diag(R), " ", sep="") 
rownames(Rnew) <- colnames(x) 
colnames(Rnew) <- paste(colnames(x), "", sep="") 
## remove upper triangle
Rnew <- as.matrix(Rnew)
Rnew[upper.tri(Rnew, diag = TRUE)] <- ""
Rnew <- as.data.frame(Rnew) 
## remove last column and return the matrix (which is now a data frame)
Rnew <- cbind(Rnew[1:length(Rnew)-1])
return(Rnew) 
}
# Correlations for Deaf
print("DEAF Correlations - Pearson's r")
[1] "DEAF Correlations - Pearson's r"
#corstarsl(lexgist_deaf)
Hmisc::rcorr(as.matrix(lexgist_deaf))$r
                    aoasl     signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.50188273  0.2569266   0.08266371   -0.25585943  0.14743346  -0.25601873
signyrs       -0.50188273  1.00000000  0.7005996   0.18321127   -0.01264108  0.27968505   0.06666998
age            0.25692660  0.70059955  1.0000000   0.27454460   -0.17264941  0.42997837  -0.12765634
gist_forward   0.08266371  0.18321127  0.2745446   1.00000000    0.01762269 -0.08155560  -0.09770666
gist_reversed -0.25585943 -0.01264108 -0.1726494   0.01762269    1.00000000  0.02667231   0.36021802
lex_forward    0.14743346  0.27968505  0.4299784  -0.08155560    0.02667231  1.00000000   0.35984892
lex_reversed  -0.25601873  0.06666998 -0.1276563  -0.09770666    0.36021802  0.35984892   1.00000000
print("DEAF Correlations - P-values")
[1] "DEAF Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_deaf))$P
                    aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                  NA 5.536857e-03 1.784812e-01    0.6698839    0.18035489  0.44533530   0.18007434
signyrs       0.005536857           NA 2.316796e-05    0.3414473    0.94810844  0.14172236   0.73113301
age           0.178481213 2.316796e-05           NA    0.1495001    0.37046625  0.01990877   0.50930544
gist_forward  0.669883883 3.414473e-01 1.495001e-01           NA    0.92770438  0.67406661   0.61409897
gist_reversed 0.180354888 9.481084e-01 3.704662e-01    0.9277044            NA  0.89076140   0.05492031
lex_forward   0.445335297 1.417224e-01 1.990877e-02    0.6740666    0.89076140          NA   0.05518766
lex_reversed  0.180074336 7.311330e-01 5.093054e-01    0.6140990    0.05492031  0.05518766           NA
cat(paste("","\n",""))
# Correlations for Hearing
print("HEARING Correlations - Pearson's r")
[1] "HEARING Correlations - Pearson's r"
#corstarsl(lexgist_hearing)
Hmisc::rcorr(as.matrix(lexgist_hearing))$r
                    aoasl     signyrs       age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.07887013 0.3468184  -0.15525565    0.07815751  0.02500269   0.01411303
signyrs       -0.07887013  1.00000000 0.9021947   0.57814670    0.28845748  0.36725658   0.20828810
age            0.34681845  0.90219468 1.0000000   0.44651473    0.30963454  0.30931753   0.20139593
gist_forward  -0.15525565  0.57814670 0.4465147   1.00000000    0.29502174  0.57154566   0.07645807
gist_reversed  0.07815751  0.28845748 0.3096345   0.29502174    1.00000000  0.35682374   0.57951176
lex_forward    0.02500269  0.36725658 0.3093175   0.57154566    0.35682374  1.00000000   0.36558339
lex_reversed   0.01411303  0.20828810 0.2013959   0.07645807    0.57951176  0.36558339   1.00000000
print("HEARING Correlations - P-values")
[1] "HEARING Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_hearing))$P
                  aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                NA 7.205586e-01 1.049514e-01  0.479339909   0.722986497 0.909841021  0.949040176
signyrs       0.7205586           NA 4.046899e-09  0.003857505   0.181932462 0.084723426  0.340222805
age           0.1049514 4.046899e-09           NA  0.032691671   0.150502508 0.150942632  0.356794880
gist_forward  0.4793399 3.857505e-03 3.269167e-02           NA   0.171744860 0.004385475  0.728786878
gist_reversed 0.7229865 1.819325e-01 1.505025e-01  0.171744860            NA 0.094647552  0.003755275
lex_forward   0.9098410 8.472343e-02 1.509426e-01  0.004385475   0.094647552          NA  0.086260140
lex_reversed  0.9490402 3.402228e-01 3.567949e-01  0.728786878   0.003755275 0.086260140           NA
cat(paste("","\n",""))
# Correlations for All
print("ALL Correlations - Pearson's r")
[1] "ALL Correlations - Pearson's r"
#corstarsl(lexgist_all)
Hmisc::rcorr(as.matrix(lexgist_all))$r
                    aoasl    signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.7852245 -0.3136458   -0.3230903    -0.3922803 -0.08115845   -0.3394521
signyrs       -0.78522450  1.0000000  0.8314757    0.4956183     0.3356193  0.29698992    0.3182316
age           -0.31364575  0.8314757  1.0000000    0.4602616     0.1930257  0.36318284    0.1886432
gist_forward  -0.32309031  0.4956183  0.4602616    1.0000000     0.2712761  0.49279109    0.1521110
gist_reversed -0.39228034  0.3356193  0.1930257    0.2712761     1.0000000  0.21701819    0.4921550
lex_forward   -0.08115845  0.2969899  0.3631828    0.4927911     0.2170182  1.00000000    0.3800772
lex_reversed  -0.33945209  0.3182316  0.1886432    0.1521110     0.4921550  0.38007715    1.0000000
print("ALL Correlations - P-values")
[1] "ALL Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_all))$P
                     aoasl      signyrs          age gist_forward gist_reversed  lex_forward
aoasl                   NA 5.523138e-12 2.356068e-02 0.0194786567  0.0040239673 0.5673489939
signyrs       5.523138e-12           NA 2.309264e-14 0.0001870211  0.0150006737 0.0325116001
age           2.356068e-02 2.309264e-14           NA 0.0005965582  0.1703671221 0.0081373882
gist_forward  1.947866e-02 1.870211e-04 5.965582e-04           NA  0.0517394597 0.0002061625
gist_reversed 4.023967e-03 1.500067e-02 1.703671e-01 0.0517394597            NA 0.1222542968
lex_forward   5.673490e-01 3.251160e-02 8.137388e-03 0.0002061625  0.1222542968           NA
lex_reversed  1.382018e-02 2.149676e-02 1.804672e-01 0.2817023354  0.0002107074 0.0054478274
              lex_reversed
aoasl         0.0138201778
signyrs       0.0214967644
age           0.1804672184
gist_forward  0.2817023354
gist_reversed 0.0002107074
lex_forward   0.0054478274
lex_reversed            NA

I’m also including nicely formatted tables with *** indicators of significance for quick referencing. Order: Deaf, Hearing, All.

corstarsl(lexgist_deaf)
corstarsl(lexgist_hearing)
corstarsl(lexgist_all)

Scatterplot of Correlations

Let’s visualize what’s happening with the correlations here.

ggpairs(lexgist_data, columns = c(2:8), aes(color = hearing))

 plot: [1,1] [==------------------------------------------------------------------------]  2% est: 0s 
 plot: [1,2] [===-----------------------------------------------------------------------]  4% est: 5s 
 plot: [1,3] [=====---------------------------------------------------------------------]  6% est: 5s 
 plot: [1,4] [======--------------------------------------------------------------------]  8% est: 5s 
 plot: [1,5] [========------------------------------------------------------------------] 10% est: 5s 
 plot: [1,6] [=========-----------------------------------------------------------------] 12% est: 5s 
 plot: [1,7] [===========---------------------------------------------------------------] 14% est: 4s 
 plot: [2,1] [============--------------------------------------------------------------] 16% est: 4s 
 plot: [2,2] [==============------------------------------------------------------------] 18% est: 4s 
 plot: [2,3] [===============-----------------------------------------------------------] 20% est: 4s 
 plot: [2,4] [=================---------------------------------------------------------] 22% est: 4s 
 plot: [2,5] [==================--------------------------------------------------------] 24% est: 4s 
 plot: [2,6] [====================------------------------------------------------------] 27% est: 4s 
 plot: [2,7] [=====================-----------------------------------------------------] 29% est: 4s 
 plot: [3,1] [=======================---------------------------------------------------] 31% est: 4s 
 plot: [3,2] [========================--------------------------------------------------] 33% est: 3s 
 plot: [3,3] [==========================------------------------------------------------] 35% est: 3s 
 plot: [3,4] [===========================-----------------------------------------------] 37% est: 3s 
 plot: [3,5] [=============================---------------------------------------------] 39% est: 3s 
 plot: [3,6] [==============================--------------------------------------------] 41% est: 3s 
 plot: [3,7] [================================------------------------------------------] 43% est: 3s 
 plot: [4,1] [=================================-----------------------------------------] 45% est: 3s 
 plot: [4,2] [===================================---------------------------------------] 47% est: 3s 
 plot: [4,3] [====================================--------------------------------------] 49% est: 3s 
 plot: [4,4] [======================================------------------------------------] 51% est: 3s 
 plot: [4,5] [=======================================-----------------------------------] 53% est: 2s 
 plot: [4,6] [=========================================---------------------------------] 55% est: 2s 
 plot: [4,7] [==========================================--------------------------------] 57% est: 2s 
 plot: [5,1] [============================================------------------------------] 59% est: 2s 
 plot: [5,2] [=============================================-----------------------------] 61% est: 2s 
 plot: [5,3] [===============================================---------------------------] 63% est: 2s 
 plot: [5,4] [================================================--------------------------] 65% est: 2s 
 plot: [5,5] [==================================================------------------------] 67% est: 2s 
 plot: [5,6] [===================================================-----------------------] 69% est: 2s 
 plot: [5,7] [=====================================================---------------------] 71% est: 2s 
 plot: [6,1] [======================================================--------------------] 73% est: 1s 
 plot: [6,2] [========================================================------------------] 76% est: 1s 
 plot: [6,3] [=========================================================-----------------] 78% est: 1s 
 plot: [6,4] [===========================================================---------------] 80% est: 1s 
 plot: [6,5] [============================================================--------------] 82% est: 1s 
 plot: [6,6] [==============================================================------------] 84% est: 1s 
 plot: [6,7] [===============================================================-----------] 86% est: 1s 
 plot: [7,1] [=================================================================---------] 88% est: 1s 
 plot: [7,2] [==================================================================--------] 90% est: 1s 
 plot: [7,3] [====================================================================------] 92% est: 0s 
 plot: [7,4] [=====================================================================-----] 94% est: 0s 
 plot: [7,5] [=======================================================================---] 96% est: 0s 
 plot: [7,6] [========================================================================--] 98% est: 0s 
 plot: [7,7] [==========================================================================]100% est: 0s 
                                                                                                      

Eye Gaze Data

Now eye gaze data. Boxplots first. Also here, we’re renaming “chin” to “neck” because that’s what it actually is! But we also have to fix all NA’s in the percentages to zeros, becuase that’s what they actually are.

# rename chin to neck
fulldata <- fulldata %>%
  rename(neck = chin) %>%
  gather(aoi, percent, belly:upperchest)
# Fix all NA's in Percent column to 0
fixpercent <- fulldata$percent
fulldata$percent <- coalesce(fixpercent, 0)
fulldata <- fulldata %>%
  spread(aoi, percent)
fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(direction, belly:upperchest) %>%
  gather(aoi, percent, belly:upperchest) %>%
  ggplot(aes(x = aoi, y = percent, fill = direction)) + geom_boxplot()

But let’s try error charts too! Instead of boxplots.

fulldata_error <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  gather(aoi, percent, belly:upperchest) %>%
  group_by(id, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm = TRUE)) %>%
  ungroup() %>%
  distinct() %>%
  group_by(direction, aoi) %>%
  summarise(mean = mean(percent, na.rm = TRUE),
            sd = sd(percent, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count))
fulldata_error$aoi <- fct_relevel(fulldata_error$aoi, c("forehead","eyes","mouth","neck","upperchest",
                                                        "midchest","lowerchest","belly","left","right"))
fulldata_error %>%
  ggplot(aes(x = aoi, y = mean, fill = direction)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Eye Gaze Behavior", x = "", y = "looking time") +
  scale_y_continuous(labels = percent, limits = c(0,.70)) + 
  theme_bw() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1, vjust = 1))

And a table of eye gaze results too

fulldata_gazetable <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  gather(aoi, percent, belly:upperchest) %>%
  group_by(id, maingroup, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm = TRUE)) %>%
  ungroup() %>%
  distinct() %>%
  group_by(maingroup, direction, aoi) %>%
  summarise(mean = mean(percent, na.rm = TRUE),
            sd = sd(percent, na.rm = TRUE)) %>%
  mutate(mean = round(mean*100,1),
         sd = round(sd*100,1)) %>%
  mutate(value = paste(mean, sd, sep = " ± ")) %>%
  mutate(value = paste(value, "%", sep = ""))
fulldata_gazetable$aoi <- fct_relevel(fulldata_gazetable$aoi, c("forehead","eyes","mouth","neck","upperchest",
                                                        "midchest","lowerchest","belly","left","right"))
fulldata_gazetable %>% 
  ungroup() %>%
  select(-mean, -sd) %>% 
  spread(aoi, value)
fulldata_total <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  gather(aoi, percent, belly:upperchest) %>%
  group_by(aoi) %>%
  summarise(percent = mean(percent, na.rm = TRUE)) %>%
  spread(aoi, percent)
#sum(fulldata_total$eyes, fulldata_total$mouth, fulldata_total$neck)
#fulldata_total$left
#fulldata_total$right

Big Three-Way ANOVA

Now we’re going to try a three-way Group x Direction x AOI ANOVA with the top 3 AOIs (Eyes, Mouth, Neck)

$ANOVA
                   Effect DFn DFd          F            p p<.05          ges
2               maingroup   3  47  3.0877532 3.602912e-02     * 0.0019613548
3               direction   1  47 14.6917045 3.751848e-04     * 0.0008045246
5                     aoi   2  94 38.9261560 4.838451e-13     * 0.4115853001
4     maingroup:direction   3  47  0.8509636 4.731139e-01       0.0001398905
6           maingroup:aoi   6  94  1.1224334 3.553342e-01       0.0570561521
7           direction:aoi   2  94  7.0028846 1.462185e-03     * 0.0208462714
8 maingroup:direction:aoi   6  94  0.6318533 7.044042e-01       0.0057298396

Left Vs Right

$ANOVA
         Effect DFn DFd         F          p p<.05        ges
2     maingroup   3  47 2.5418616 0.06755936       0.09343220
3           aoi   1  47 1.8880127 0.17594392       0.01444195
4 maingroup:aoi   3  47 0.8434728 0.47700559       0.01926124

Interactions Visualization

So we have significant maingroup:aoi and direction:aoi interactions. Let’s try to visualize what can be driving these. We can go back to the SEM chart but break it down…

First are the maingroup:aoi charts The error bars are not 100% accurate, I took a quick-n-easy way around

aoi3_interactions_maingroupaoi <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(id, participant, maingroup, direction, eyes, mouth, neck) %>%
  gather(aoi, percent, c(eyes, mouth, neck)) %>%
  group_by(id, maingroup, direction, aoi) %>%
  mutate(percent = mean(percent, na.rm = TRUE)) %>%
  distinct() %>%
  group_by(maingroup, aoi) %>%
  summarise(mean = mean(percent, na.rm = TRUE),
            sd = sd(percent, na.rm = TRUE),
            count = n()/2,
            se = sd/sqrt(count))
# I need to first collapse across stories for each participant...here I didn't. Must fix later.
aoi3_interactions_maingroupaoi %>% 
  ggplot(aes(x = aoi, y = mean, fill = maingroup)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "MainGroup & AOI Interaction 1", subtitle = "Error bars represent SE", x = "", y = "percent looking") +
  scale_y_continuous(labels = percent)

aoi3_interactions_maingroupaoi %>% 
  ggplot(aes(x = maingroup, y = mean, fill = aoi)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "MainGroup & AOI Interaction 2", subtitle = "Error bars represent SE", x = "", y = "percent looking") +
  scale_y_continuous(labels = percent)

First are the direction:aoi charts The error bars are not 100% accurate, I took a quick-n-easy way around

aoi3_interactions_directionaoi <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(id, participant, maingroup, direction, eyes, mouth, neck) %>%
  gather(aoi, percent, c(eyes, mouth, neck)) %>%
  group_by(id, maingroup, direction, aoi) %>%
  mutate(percent = mean(percent, na.rm = TRUE)) %>%
  distinct() %>%
  group_by(direction, aoi) %>%
  summarise(mean = mean(percent, na.rm = TRUE),
            sd = sd(percent, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count))
# I need to first collapse across stories for each participant...here I didn't. Must fix later.
aoi3_interactions_directionaoi %>% 
  ggplot(aes(x = aoi, y = mean, fill = direction)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "MainGroup & Direction Interaction 1", subtitle = "Error bars represent SE", x = "", y = "percent looking") +
  scale_y_continuous(labels = percent)

aoi3_interactions_directionaoi %>% 
  ggplot(aes(x = direction, y = mean, fill = aoi)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "MainGroup & Direction Interaction 2", subtitle = "Error bars represent SE", x = "", y = "percent looking") +
  scale_y_continuous(labels = percent)

All the AOI means

Let’s get tables of our means here, in various configurations

Eyes

  1. ANOVA with factors MainGroup & Direction.
Converting "id" to factor for ANOVA.Converting "direction" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Reverse only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA

Mouth

  1. ANOVA with factors MainGroup & Direction.
Converting "id" to factor for ANOVA.Converting "direction" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Reverse only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA

Neck

  1. ANOVA with factors MainGroup & Direction.
Converting "id" to factor for ANOVA.Converting "direction" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Reverse only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA

FaceChest

We originally defined FaceChest such that

  1. Face = eyes + mouth + chin
  2. Chest = upperchest + midchest + lowerchest

BUT. Chin is actually neck. It’s not even part of the face if you think about it. So I’m redefining FaceChest as:

  1. Face = forehead + eyes + mouth
  2. Chest = neck + upperchest + midchest + lowerchest

So let’s do this. Then see what’s happening across groups for FaceChest.

Cool. Next we’ll do error bar charts using the new FaceChest across groups.

facechest_info <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  group_by(maingroup, direction, participant) %>%
  summarise(facechest = mean(facechest, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(facechest),
            sd = sd(facechest),
            n = n(),
            se = sd/sqrt(n)) %>%
  ungroup() %>%
  mutate(maingroup = case_when(
    maingroup == "DeafEarly" ~ "Deaf Early",
    maingroup == "DeafLate" ~ "Deaf Late",
    maingroup == "HearingLate" ~ "Hearing Late",
    maingroup == "HearingNovice" ~ "Hearing Novice"
    ))
ggplot(facechest_info, aes(x = maingroup, y = mean, fill = direction, color = direction)) +
  geom_point(stat = "identity", position = position_dodge(0.5), size = 2) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.5), width = 0.3, size = 1) +
  labs(title = "Face-Chest Ratio", x = "", y = "face-chest ratio") +
  scale_y_continuous(limits = c(-1,1)) + 
  geom_hline(yintercept = 0, linetype = "dotted") +
  theme_bw()

Now let’s do the ANOVAs. Also skipping LSDs here.

  1. ANOVA with factors MainGroup & Direction.
Grouping rowwise data frame strips rowwise natureConverting "id" to factor for ANOVA.Converting "direction" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Forward only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA
  1. ANOVA with factor MainGroup, for Reverse only.
Converting "id" to factor for ANOVA.Converting "maingroup" to factor for ANOVA.Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
$ANOVA
NA

Eye Gaze & Performance Correlations

Next we’re going to correlate our eye gaze metrics (Eye, Mouth, Neck, and FaceChest) with lexical recall and gist. Okay! But remember we have a slightly smaller dataset here because we’ve excluded some participants for having bad eye data (but they had valid behavioral data so we kept them in the AoA-Performance correlations above).

We also removed gist_forward column.

eyeperf <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(participant, maingroup, hearing, direction, aoasl, signyrs, acc, gist, eyes, mouth, neck, facechest) %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         lex = mean(acc, na.rm = TRUE),
         eyes = mean(eyes, na.rm = TRUE),
         mouth = mean(mouth, na.rm = TRUE),
         neck = mean(neck, na.rm = TRUE),
         facechest = mean(facechest, na.rm = TRUE)) %>%
  ungroup() %>%
  select(maingroup, participant, hearing, direction, aoasl, signyrs, gist, lex, eyes, mouth, neck, facechest) %>%
  distinct() %>%
  gather(metric, value, gist:facechest) %>%
  unite(metricvalue, c(metric, direction), sep = "_") %>%
  spread(metricvalue, value) %>%
  select(-participant, -maingroup) %>%
  select(hearing, aoasl, signyrs, gist_reversed, lex_forward, lex_reversed, eyes_forward, eyes_reversed,
         mouth_forward, mouth_reversed, neck_forward, neck_reversed, facechest_forward, facechest_reversed)
Grouping rowwise data frame strips rowwise nature
eyeperf_deaf <- eyeperf %>% filter(hearing == "Deaf") %>% select(-hearing)
eyeperf_hearing <- eyeperf %>% filter(hearing == "Hearing") %>% select(-hearing)
eyeperf_all <- eyeperf %>% select(-hearing)
# Correlations for Deaf
print("DEAF Correlations - Pearson's r")
[1] "DEAF Correlations - Pearson's r"
#corstarsl(lexgist_deaf)
Hmisc::rcorr(as.matrix(eyeperf_deaf))$r
                         aoasl      signyrs gist_reversed lex_forward lex_reversed eyes_forward
aoasl               1.00000000 -0.501882732   -0.22660857   0.1172403  -0.16780065   0.06486298
signyrs            -0.50188273  1.000000000   -0.10665206   0.3851766  -0.02521074   0.08415831
gist_reversed      -0.22660857 -0.106652059    1.00000000  -0.1103272   0.30316901  -0.06319147
lex_forward         0.11724032  0.385176599   -0.11032724   1.0000000   0.12103733   0.19560269
lex_reversed       -0.16780065 -0.025210742    0.30316901   0.1210373   1.00000000  -0.09834590
eyes_forward        0.06486298  0.084158309   -0.06319147   0.1956027  -0.09834590   1.00000000
eyes_reversed       0.02247978  0.095836595    0.02254098   0.1946094  -0.07989090   0.53012073
mouth_forward       0.17733160  0.093835786    0.13998124   0.1127365   0.13984634  -0.40389580
mouth_reversed      0.30344567  0.007193097    0.06590948   0.1511229   0.11828493  -0.18798503
neck_forward       -0.23936971 -0.133463204   -0.10845388  -0.2818219  -0.06254636  -0.40213531
neck_reversed      -0.32970390 -0.052028485   -0.07553297  -0.2951812  -0.01236971  -0.29756692
facechest_forward   0.25001433  0.150099218    0.10233361   0.2796232   0.05057043   0.37868726
facechest_reversed  0.30789807  0.086108170    0.08644924   0.3039166   0.03749677   0.28118142
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl                 0.02247978    0.17733160    0.303445667  -0.23936971   -0.32970390
signyrs               0.09583659    0.09383579    0.007193097  -0.13346320   -0.05202848
gist_reversed         0.02254098    0.13998124    0.065909483  -0.10845388   -0.07553297
lex_forward           0.19460939    0.11273646    0.151122898  -0.28182188   -0.29518121
lex_reversed         -0.07989090    0.13984634    0.118284926  -0.06254636   -0.01236971
eyes_forward          0.53012073   -0.40389580   -0.187985033  -0.40213531   -0.29756692
eyes_reversed         1.00000000   -0.10849377   -0.451476872  -0.32258892   -0.42235607
mouth_forward        -0.10849377    1.00000000    0.648739517  -0.66524893   -0.54832852
mouth_reversed       -0.45147687    0.64873952    1.000000000  -0.52286172   -0.59771758
neck_forward         -0.32258892   -0.66524893   -0.522861719   1.00000000    0.82565296
neck_reversed        -0.42235607   -0.54832852   -0.597717583   0.82565296    1.00000000
facechest_forward     0.32650983    0.69180554    0.496383160  -0.99141806   -0.79461950
facechest_reversed    0.43328831    0.58112735    0.598425627  -0.83648926   -0.99196124
                   facechest_forward facechest_reversed
aoasl                     0.25001433         0.30789807
signyrs                   0.15009922         0.08610817
gist_reversed             0.10233361         0.08644924
lex_forward               0.27962315         0.30391663
lex_reversed              0.05057043         0.03749677
eyes_forward              0.37868726         0.28118142
eyes_reversed             0.32650983         0.43328831
mouth_forward             0.69180554         0.58112735
mouth_reversed            0.49638316         0.59842563
neck_forward             -0.99141806        -0.83648926
neck_reversed            -0.79461950        -0.99196124
facechest_forward         1.00000000         0.81218421
facechest_reversed        0.81218421         1.00000000
print("DEAF Correlations - P-values")
[1] "DEAF Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_deaf))$P
                         aoasl     signyrs gist_reversed lex_forward lex_reversed eyes_forward
aoasl                       NA 0.005536857     0.2462148  0.54472632    0.3933760  0.738164157
signyrs            0.005536857          NA     0.5890836  0.03907663    0.8986709  0.664257588
gist_reversed      0.246214823 0.589083649            NA  0.57623604    0.1168234  0.749383585
lex_forward        0.544726321 0.039076627     0.5762360          NA    0.5395250  0.309208485
lex_reversed       0.393375956 0.898670879     0.1168234  0.53952504           NA  0.618567671
eyes_forward       0.738164157 0.664257588     0.7493836  0.30920849    0.6185677           NA
eyes_reversed      0.909600391 0.627592567     0.9093553  0.32102372    0.6861273  0.003712324
mouth_forward      0.357428170 0.628269399     0.4774249  0.56039098    0.4778537  0.029787577
mouth_reversed     0.116473224 0.971021367     0.7389667  0.44270508    0.5488533  0.338088512
neck_forward       0.211072759 0.490065680     0.5827693  0.13857704    0.7518624  0.030576543
neck_reversed      0.086644292 0.792600787     0.7024562  0.12727155    0.9501866  0.124081940
facechest_forward  0.190862018 0.437057268     0.6043367  0.14181424    0.7982931  0.042791159
facechest_reversed 0.110944251 0.663069865     0.6618134  0.11587894    0.8497523  0.147206817
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl                0.909600391  3.574282e-01   0.1164732242 2.110728e-01  8.664429e-02
signyrs              0.627592567  6.282694e-01   0.9710213673 4.900657e-01  7.926008e-01
gist_reversed        0.909355255  4.774249e-01   0.7389666674 5.827693e-01  7.024562e-01
lex_forward          0.321023718  5.603910e-01   0.4427050811 1.385770e-01  1.272716e-01
lex_reversed         0.686127314  4.778537e-01   0.5488532932 7.518624e-01  9.501866e-01
eyes_forward         0.003712324  2.978758e-02   0.3380885118 3.057654e-02  1.240819e-01
eyes_reversed                 NA  5.826299e-01   0.0158823163 9.408046e-02  2.515937e-02
mouth_forward        0.582629892            NA   0.0001883815 8.235941e-05  2.519354e-03
mouth_reversed       0.015882316  1.883815e-04             NA 4.307483e-03  7.826592e-04
neck_forward         0.094080464  8.235941e-05   0.0043074830           NA  6.358068e-08
neck_reversed        0.025159368  2.519354e-03   0.0007826592 6.358068e-08            NA
facechest_forward    0.089925263  3.228725e-05   0.0072161132 0.000000e+00  4.429714e-07
facechest_reversed   0.021262891  1.183228e-03   0.0007685904 2.946681e-08  0.000000e+00
                   facechest_forward facechest_reversed
aoasl                   1.908620e-01       1.109443e-01
signyrs                 4.370573e-01       6.630699e-01
gist_reversed           6.043367e-01       6.618134e-01
lex_forward             1.418142e-01       1.158789e-01
lex_reversed            7.982931e-01       8.497523e-01
eyes_forward            4.279116e-02       1.472068e-01
eyes_reversed           8.992526e-02       2.126289e-02
mouth_forward           3.228725e-05       1.183228e-03
mouth_reversed          7.216113e-03       7.685904e-04
neck_forward            0.000000e+00       2.946681e-08
neck_reversed           4.429714e-07       0.000000e+00
facechest_forward                 NA       1.541998e-07
facechest_reversed      1.541998e-07                 NA
cat(paste("","\n",""))
# Correlations for Hearing
print("HEARING Correlations - Pearson's r")
[1] "HEARING Correlations - Pearson's r"
#corstarsl(lexgist_hearing)
Hmisc::rcorr(as.matrix(eyeperf_hearing))$r
                         aoasl     signyrs gist_reversed lex_forward lex_reversed eyes_forward
aoasl               1.00000000 -0.07887013   0.078157514  0.08908092   0.06994864   -0.3113572
signyrs            -0.07887013  1.00000000   0.288457483  0.26130641   0.22209269    0.1324982
gist_reversed       0.07815751  0.28845748   1.000000000  0.32119471   0.61989301   -0.2017262
lex_forward         0.08908092  0.26130641   0.321194708  1.00000000   0.23279549   -0.2064124
lex_reversed        0.06994864  0.22209269   0.619893014  0.23279549   1.00000000   -0.0936432
eyes_forward       -0.31135717  0.13249823  -0.201726153 -0.20641239  -0.09364320    1.0000000
eyes_reversed      -0.23457415  0.30698404  -0.003896097 -0.04361310  -0.12855424    0.7946519
mouth_forward       0.17806749  0.06609090  -0.022039175  0.04471777  -0.12913127   -0.7573641
mouth_reversed      0.06256448  0.04730904  -0.057827983 -0.08355581   0.01769962   -0.4947033
neck_forward        0.38414940 -0.24596132   0.367403537  0.36551589   0.36037686   -0.5478414
neck_reversed       0.29446188 -0.38249552   0.223993644  0.27462074   0.24863580   -0.5678435
facechest_forward  -0.28903425  0.30186427  -0.340341955 -0.28030962  -0.29633671    0.5328411
facechest_reversed -0.20474470  0.43157929  -0.163039193 -0.15098999  -0.19097045    0.5098403
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl               -0.234574154    0.17806749     0.06256448    0.3841494    0.29446188
signyrs              0.306984037    0.06609090     0.04730904   -0.2459613   -0.38249552
gist_reversed       -0.003896097   -0.02203918    -0.05782798    0.3674035    0.22399364
lex_forward         -0.043613102    0.04471777    -0.08355581    0.3655159    0.27462074
lex_reversed        -0.128554240   -0.12913127     0.01769962    0.3603769    0.24863580
eyes_forward         0.794651926   -0.75736409    -0.49470326   -0.5478414   -0.56784350
eyes_reversed        1.000000000   -0.53289974    -0.60845947   -0.5244592   -0.66767001
mouth_forward       -0.532899737    1.00000000     0.73505580   -0.0809406    0.06470188
mouth_reversed      -0.608459473    0.73505580     1.00000000   -0.0758556   -0.09060995
neck_forward        -0.524459183   -0.08094060    -0.07585560    1.0000000    0.76188785
neck_reversed       -0.667670012    0.06470188    -0.09060995    0.7618878    1.00000000
facechest_forward    0.513289094    0.14471392     0.19576141   -0.9424162   -0.78331023
facechest_reversed   0.602644563    0.05395970     0.23728788   -0.7260022   -0.93513525
                   facechest_forward facechest_reversed
aoasl                     -0.2890342         -0.2047447
signyrs                    0.3018643          0.4315793
gist_reversed             -0.3403420         -0.1630392
lex_forward               -0.2803096         -0.1509900
lex_reversed              -0.2963367         -0.1909705
eyes_forward               0.5328411          0.5098403
eyes_reversed              0.5132891          0.6026446
mouth_forward              0.1447139          0.0539597
mouth_reversed             0.1957614          0.2372879
neck_forward              -0.9424162         -0.7260022
neck_reversed             -0.7833102         -0.9351352
facechest_forward          1.0000000          0.8350726
facechest_reversed         0.8350726          1.0000000
print("HEARING Correlations - P-values")
[1] "HEARING Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_hearing))$P
                        aoasl    signyrs gist_reversed lex_forward lex_reversed eyes_forward
aoasl                      NA 0.72055862   0.722986497  0.68606718  0.751135086 1.481267e-01
signyrs            0.72055862         NA   0.181932462  0.22845065  0.308433949 5.467283e-01
gist_reversed      0.72298650 0.18193246            NA  0.13506603  0.001604978 3.559903e-01
lex_forward        0.68606718 0.22845065   0.135066028          NA  0.285087190 3.446869e-01
lex_reversed       0.75113509 0.30843395   0.001604978  0.28508719           NA 6.708451e-01
eyes_forward       0.14812668 0.54672830   0.355990294  0.34468693  0.670845077           NA
eyes_reversed      0.28131767 0.15421037   0.985923639  0.84336552  0.558831962 5.929025e-06
mouth_forward      0.41628381 0.76447263   0.920492311  0.83944758  0.557053614 2.859607e-05
mouth_reversed     0.77672173 0.83027171   0.793254811  0.70466052  0.936112687 1.640479e-02
neck_forward       0.07033578 0.25793084   0.084589444  0.08632257  0.091175442 6.807338e-03
neck_reversed      0.17259799 0.07165620   0.304204139  0.20474801  0.252624987 4.707219e-03
facechest_forward  0.18102107 0.16155367   0.112046749  0.19514544  0.169752614 8.849713e-03
facechest_reversed 0.34868489 0.03975328   0.457300336  0.49164189  0.382738792 1.294574e-02
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl               2.813177e-01  4.162838e-01   7.767217e-01 7.033578e-02  1.725980e-01
signyrs             1.542104e-01  7.644726e-01   8.302717e-01 2.579308e-01  7.165620e-02
gist_reversed       9.859236e-01  9.204923e-01   7.932548e-01 8.458944e-02  3.042041e-01
lex_forward         8.433655e-01  8.394476e-01   7.046605e-01 8.632257e-02  2.047480e-01
lex_reversed        5.588320e-01  5.570536e-01   9.361127e-01 9.117544e-02  2.526250e-01
eyes_forward        5.929025e-06  2.859607e-05   1.640479e-02 6.807338e-03  4.707219e-03
eyes_reversed                 NA  8.840848e-03   2.065194e-03 1.019589e-02  4.996113e-04
mouth_forward       8.840848e-03            NA   6.461917e-05 7.135195e-01  7.692911e-01
mouth_reversed      2.065194e-03  6.461917e-05             NA 7.308466e-01  6.809521e-01
neck_forward        1.019589e-02  7.135195e-01   7.308466e-01           NA  2.398635e-05
neck_reversed       4.996113e-04  7.692911e-01   6.809521e-01 2.398635e-05            NA
facechest_forward   1.224782e-02  5.100229e-01   3.706863e-01 1.861311e-11  9.878377e-06
facechest_reversed  2.339301e-03  8.068219e-01   2.756272e-01 8.797435e-05  6.290368e-11
                   facechest_forward facechest_reversed
aoasl                   1.810211e-01       3.486849e-01
signyrs                 1.615537e-01       3.975328e-02
gist_reversed           1.120467e-01       4.573003e-01
lex_forward             1.951454e-01       4.916419e-01
lex_reversed            1.697526e-01       3.827388e-01
eyes_forward            8.849713e-03       1.294574e-02
eyes_reversed           1.224782e-02       2.339301e-03
mouth_forward           5.100229e-01       8.068219e-01
mouth_reversed          3.706863e-01       2.756272e-01
neck_forward            1.861311e-11       8.797435e-05
neck_reversed           9.878377e-06       6.290368e-11
facechest_forward                 NA       7.177950e-07
facechest_reversed      7.177950e-07                 NA
cat(paste("","\n",""))
# Correlations for All
print("ALL Correlations - Pearson's r")
[1] "ALL Correlations - Pearson's r"
#corstarsl(lexgist_all)
Hmisc::rcorr(as.matrix(eyeperf_all))$r
                         aoasl     signyrs gist_reversed  lex_forward lex_reversed eyes_forward
aoasl               1.00000000 -0.78522450 -0.3232638240 -0.142631680  -0.25779733    0.1023350
signyrs            -0.78522450  1.00000000  0.2341087610  0.363347173   0.24984565   -0.0971436
gist_reversed      -0.32326382  0.23410876  1.0000000000  0.157367334   0.44831455   -0.1583381
lex_forward        -0.14263168  0.36334717  0.1573673338  1.000000000   0.23866823   -0.1346806
lex_reversed       -0.25779733  0.24984565  0.4483145475  0.238668233   1.00000000   -0.1345993
eyes_forward        0.10233497 -0.09714360 -0.1583380550 -0.134680599  -0.13459931    1.0000000
eyes_reversed       0.08366051 -0.02729736 -0.0331474617 -0.007873518  -0.14027905    0.7066929
mouth_forward      -0.06004520  0.21724346  0.1270669401  0.116687804   0.05451585   -0.6230710
mouth_reversed     -0.08601686  0.25058311  0.1034677997  0.081888258   0.14056188   -0.3857141
neck_forward       -0.12643635 -0.03886278  0.0342302844  0.051669102   0.10643122   -0.4273281
neck_reversed      -0.09436191 -0.11454841 -0.0002581948  0.003536053   0.07954131   -0.3926680
facechest_forward   0.06745102  0.12098147 -0.0335624404 -0.031654894  -0.09553912    0.4281833
facechest_reversed -0.00671559  0.23324074  0.0425947122  0.063717648  -0.02840233    0.3631589
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl                0.083660506   -0.06004520    -0.08601686  -0.12643635 -0.0943619087
signyrs             -0.027297357    0.21724346     0.25058311  -0.03886278 -0.1145484149
gist_reversed       -0.033147462    0.12706694     0.10346780   0.03423028 -0.0002581948
lex_forward         -0.007873518    0.11668780     0.08188826   0.05166910  0.0035360528
lex_reversed        -0.140279055    0.05451585     0.14056188   0.10643122  0.0795413107
eyes_forward         0.706692934   -0.62307096    -0.38571414  -0.42732805 -0.3926679790
eyes_reversed        1.000000000   -0.36512721    -0.54427344  -0.38895777 -0.5032187104
mouth_forward       -0.365127206    1.00000000     0.70370090  -0.40481210 -0.2855360210
mouth_reversed      -0.544273436    0.70370090     1.00000000  -0.31946859 -0.3897527158
neck_forward        -0.388957769   -0.40481210    -0.31946859   1.00000000  0.7993095517
neck_reversed       -0.503218710   -0.28553602    -0.38975272   0.79930955  1.0000000000
facechest_forward    0.402936906    0.43687293     0.35403353  -0.96537608 -0.7889307141
facechest_reversed   0.482238919    0.34413567     0.45460728  -0.76219910 -0.9576927423
                   facechest_forward facechest_reversed
aoasl                     0.06745102        -0.00671559
signyrs                   0.12098147         0.23324074
gist_reversed            -0.03356244         0.04259471
lex_forward              -0.03165489         0.06371765
lex_reversed             -0.09553912        -0.02840233
eyes_forward              0.42818332         0.36315894
eyes_reversed             0.40293691         0.48223892
mouth_forward             0.43687293         0.34413567
mouth_reversed            0.35403353         0.45460728
neck_forward             -0.96537608        -0.76219910
neck_reversed            -0.78893071        -0.95769274
facechest_forward         1.00000000         0.81137252
facechest_reversed        0.81137252         1.00000000
print("ALL Correlations - P-values")
[1] "ALL Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_all))$P
                          aoasl      signyrs gist_reversed lex_forward lex_reversed eyes_forward
aoasl                        NA 5.523138e-12  0.0206764715 0.313119467 0.0677889791 4.703512e-01
signyrs            5.523138e-12           NA  0.0982310781 0.008106492 0.0770305388 4.932766e-01
gist_reversed      2.067647e-02 9.823108e-02            NA 0.270089935 0.0009694904 2.671087e-01
lex_forward        3.131195e-01 8.106492e-03  0.2700899346          NA 0.0916709472 3.411308e-01
lex_reversed       6.778898e-02 7.703054e-02  0.0009694904 0.091670947           NA 3.463483e-01
eyes_forward       4.703512e-01 4.932766e-01  0.2671087463 0.341130821 0.3463483357           NA
eyes_reversed      5.594433e-01 8.491958e-01  0.8173807987 0.956269902 0.3261870511 6.830266e-09
mouth_forward      6.724059e-01 1.218575e-01  0.3742437833 0.410046028 0.7039809873 8.097570e-07
mouth_reversed     5.483940e-01 7.613369e-02  0.4699673532 0.567822001 0.3252028385 5.184763e-03
neck_forward       3.717642e-01 7.844425e-01  0.8115222617 0.716024525 0.4572739900 1.579676e-03
neck_reversed      5.101240e-01 4.234798e-01  0.9985652716 0.980352890 0.5790064531 4.369926e-03
facechest_forward  6.347056e-01 3.929129e-01  0.8151343981 0.823711779 0.5048365664 1.542092e-03
facechest_reversed 9.626962e-01 9.952016e-02  0.7666339865 0.656893631 0.8431666495 8.811831e-03
                   eyes_reversed mouth_forward mouth_reversed neck_forward neck_reversed
aoasl               5.594433e-01  6.724059e-01   5.483940e-01 3.717642e-01  5.101240e-01
signyrs             8.491958e-01  1.218575e-01   7.613369e-02 7.844425e-01  4.234798e-01
gist_reversed       8.173808e-01  3.742438e-01   4.699674e-01 8.115223e-01  9.985653e-01
lex_forward         9.562699e-01  4.100460e-01   5.678220e-01 7.160245e-01  9.803529e-01
lex_reversed        3.261871e-01  7.039810e-01   3.252028e-01 4.572740e-01  5.790065e-01
eyes_forward        6.830266e-09  8.097570e-07   5.184763e-03 1.579676e-03  4.369926e-03
eyes_reversed                 NA  8.425391e-03   3.651371e-05 4.789468e-03  1.673548e-04
mouth_forward       8.425391e-03            NA   8.423032e-09 2.913237e-03  4.224662e-02
mouth_reversed      3.651371e-05  8.423032e-09             NA 2.230426e-02  4.696719e-03
neck_forward        4.789468e-03  2.913237e-03   2.230426e-02           NA  2.037925e-12
neck_reversed       1.673548e-04  4.224662e-02   4.696719e-03 2.037925e-12            NA
facechest_forward   3.372262e-03  1.203117e-03   1.081053e-02 0.000000e+00  6.159073e-12
facechest_reversed  3.391156e-04  1.340835e-02   8.043284e-04 8.169354e-11  0.000000e+00
                   facechest_forward facechest_reversed
aoasl                   6.347056e-01       9.626962e-01
signyrs                 3.929129e-01       9.952016e-02
gist_reversed           8.151344e-01       7.666340e-01
lex_forward             8.237118e-01       6.568936e-01
lex_reversed            5.048366e-01       8.431666e-01
eyes_forward            1.542092e-03       8.811831e-03
eyes_reversed           3.372262e-03       3.391156e-04
mouth_forward           1.203117e-03       1.340835e-02
mouth_reversed          1.081053e-02       8.043284e-04
neck_forward            0.000000e+00       8.169354e-11
neck_reversed           6.159073e-12       0.000000e+00
facechest_forward                 NA       5.182521e-13
facechest_reversed      5.182521e-13                 NA

I’m also including nicely formatted tables with *** indicators of significance for quick referencing. Order: Deaf, Hearing, All.

corstarsl(eyeperf_deaf)
corstarsl(eyeperf_hearing)
corstarsl(eyeperf_all)

And the correlation table.

ggpairs(eyeperf, columns = c(2:13), aes(color = hearing))

 plot: [1,1] [=-------------------------------------------------------------------------]  1% est: 0s 
 plot: [1,2] [=-------------------------------------------------------------------------]  1% est:12s 
 plot: [1,3] [==------------------------------------------------------------------------]  2% est:13s 
 plot: [1,4] [==------------------------------------------------------------------------]  3% est:12s 
 plot: [1,5] [===-----------------------------------------------------------------------]  3% est:12s 
 plot: [1,6] [===-----------------------------------------------------------------------]  4% est:12s 
 plot: [1,7] [====----------------------------------------------------------------------]  5% est:12s 
 plot: [1,8] [====----------------------------------------------------------------------]  6% est:12s 
 plot: [1,9] [=====---------------------------------------------------------------------]  6% est:12s 
 plot: [1,10] [=====--------------------------------------------------------------------]  7% est:12s 
 plot: [1,11] [======-------------------------------------------------------------------]  8% est:12s 
 plot: [1,12] [======-------------------------------------------------------------------]  8% est:12s 
 plot: [2,1] [=======-------------------------------------------------------------------]  9% est:12s 
 plot: [2,2] [=======-------------------------------------------------------------------] 10% est:12s 
 plot: [2,3] [========------------------------------------------------------------------] 10% est:13s 
 plot: [2,4] [========------------------------------------------------------------------] 11% est:13s 
 plot: [2,5] [=========-----------------------------------------------------------------] 12% est:13s 
 plot: [2,6] [=========-----------------------------------------------------------------] 12% est:13s 
 plot: [2,7] [==========----------------------------------------------------------------] 13% est:13s 
 plot: [2,8] [==========----------------------------------------------------------------] 14% est:13s 
 plot: [2,9] [===========---------------------------------------------------------------] 15% est:13s 
 plot: [2,10] [===========--------------------------------------------------------------] 15% est:13s 
 plot: [2,11] [============-------------------------------------------------------------] 16% est:13s 
 plot: [2,12] [============-------------------------------------------------------------] 17% est:13s 
 plot: [3,1] [=============-------------------------------------------------------------] 17% est:13s 
 plot: [3,2] [=============-------------------------------------------------------------] 18% est:13s 
 plot: [3,3] [==============------------------------------------------------------------] 19% est:13s 
 plot: [3,4] [==============------------------------------------------------------------] 19% est:13s 
 plot: [3,5] [===============-----------------------------------------------------------] 20% est:13s 
 plot: [3,6] [===============-----------------------------------------------------------] 21% est:13s 
 plot: [3,7] [================----------------------------------------------------------] 22% est:13s 
 plot: [3,8] [================----------------------------------------------------------] 22% est:12s 
 plot: [3,9] [=================---------------------------------------------------------] 23% est:12s 
 plot: [3,10] [=================--------------------------------------------------------] 24% est:12s 
 plot: [3,11] [==================-------------------------------------------------------] 24% est:12s 
 plot: [3,12] [==================-------------------------------------------------------] 25% est:12s 
 plot: [4,1] [===================-------------------------------------------------------] 26% est:12s 
 plot: [4,2] [====================------------------------------------------------------] 26% est:12s 
 plot: [4,3] [====================------------------------------------------------------] 27% est:12s 
 plot: [4,4] [=====================-----------------------------------------------------] 28% est:12s 
 plot: [4,5] [=====================-----------------------------------------------------] 28% est:12s 
 plot: [4,6] [======================----------------------------------------------------] 29% est:12s 
 plot: [4,7] [======================----------------------------------------------------] 30% est:12s 
 plot: [4,8] [=======================---------------------------------------------------] 31% est:12s 
 plot: [4,9] [=======================---------------------------------------------------] 31% est:12s 
 plot: [4,10] [=======================--------------------------------------------------] 32% est:12s 
 plot: [4,11] [========================-------------------------------------------------] 33% est:11s 
 plot: [4,12] [========================-------------------------------------------------] 33% est:11s 
 plot: [5,1] [=========================-------------------------------------------------] 34% est:11s 
 plot: [5,2] [==========================------------------------------------------------] 35% est:11s 
 plot: [5,3] [==========================------------------------------------------------] 35% est:11s 
 plot: [5,4] [===========================-----------------------------------------------] 36% est:11s 
 plot: [5,5] [===========================-----------------------------------------------] 37% est:11s 
 plot: [5,6] [============================----------------------------------------------] 38% est:10s 
 plot: [5,7] [============================----------------------------------------------] 38% est:10s 
 plot: [5,8] [=============================---------------------------------------------] 39% est:10s 
 plot: [5,9] [=============================---------------------------------------------] 40% est:10s 
 plot: [5,10] [=============================--------------------------------------------] 40% est:10s 
 plot: [5,11] [==============================-------------------------------------------] 41% est:10s 
 plot: [5,12] [==============================-------------------------------------------] 42% est:10s 
 plot: [6,1] [===============================-------------------------------------------] 42% est:10s 
 plot: [6,2] [================================------------------------------------------] 43% est: 9s 
 plot: [6,3] [================================------------------------------------------] 44% est: 9s 
 plot: [6,4] [=================================-----------------------------------------] 44% est: 9s 
 plot: [6,5] [=================================-----------------------------------------] 45% est: 9s 
 plot: [6,6] [==================================----------------------------------------] 46% est: 9s 
 plot: [6,7] [==================================----------------------------------------] 47% est: 9s 
 plot: [6,8] [===================================---------------------------------------] 47% est: 9s 
 plot: [6,9] [===================================---------------------------------------] 48% est: 9s 
 plot: [6,10] [===================================--------------------------------------] 49% est: 9s 
 plot: [6,11] [====================================-------------------------------------] 49% est: 8s 
 plot: [6,12] [====================================-------------------------------------] 50% est: 8s 
 plot: [7,1] [======================================------------------------------------] 51% est: 8s 
 plot: [7,2] [======================================------------------------------------] 51% est: 8s 
 plot: [7,3] [=======================================-----------------------------------] 52% est: 8s 
 plot: [7,4] [=======================================-----------------------------------] 53% est: 8s 
 plot: [7,5] [========================================----------------------------------] 53% est: 8s 
 plot: [7,6] [========================================----------------------------------] 54% est: 8s 
 plot: [7,7] [=========================================---------------------------------] 55% est: 8s 
 plot: [7,8] [=========================================---------------------------------] 56% est: 7s 
 plot: [7,9] [==========================================--------------------------------] 56% est: 7s 
 plot: [7,10] [==========================================-------------------------------] 57% est: 7s 
 plot: [7,11] [==========================================-------------------------------] 58% est: 7s 
 plot: [7,12] [===========================================------------------------------] 58% est: 7s 
 plot: [8,1] [============================================------------------------------] 59% est: 7s 
 plot: [8,2] [============================================------------------------------] 60% est: 7s 
 plot: [8,3] [=============================================-----------------------------] 60% est: 7s 
 plot: [8,4] [=============================================-----------------------------] 61% est: 7s 
 plot: [8,5] [==============================================----------------------------] 62% est: 6s 
 plot: [8,6] [==============================================----------------------------] 62% est: 6s 
 plot: [8,7] [===============================================---------------------------] 63% est: 6s 
 plot: [8,8] [===============================================---------------------------] 64% est: 6s 
 plot: [8,9] [================================================--------------------------] 65% est: 6s 
 plot: [8,10] [================================================-------------------------] 65% est: 6s 
 plot: [8,11] [================================================-------------------------] 66% est: 6s 
 plot: [8,12] [=================================================------------------------] 67% est: 6s 
 plot: [9,1] [==================================================------------------------] 67% est: 6s 
 plot: [9,2] [==================================================------------------------] 68% est: 5s 
 plot: [9,3] [===================================================-----------------------] 69% est: 5s 
 plot: [9,4] [===================================================-----------------------] 69% est: 5s 
 plot: [9,5] [====================================================----------------------] 70% est: 5s 
 plot: [9,6] [====================================================----------------------] 71% est: 5s 
 plot: [9,7] [=====================================================---------------------] 72% est: 5s 
 plot: [9,8] [=====================================================---------------------] 72% est: 5s 
 plot: [9,9] [======================================================--------------------] 73% est: 5s 
 plot: [9,10] [======================================================-------------------] 74% est: 5s 
 plot: [9,11] [======================================================-------------------] 74% est: 4s 
 plot: [9,12] [=======================================================------------------] 75% est: 4s 
 plot: [10,1] [=======================================================------------------] 76% est: 4s 
 plot: [10,2] [========================================================-----------------] 76% est: 4s 
 plot: [10,3] [========================================================-----------------] 77% est: 4s 
 plot: [10,4] [=========================================================----------------] 78% est: 4s 
 plot: [10,5] [=========================================================----------------] 78% est: 4s 
 plot: [10,6] [==========================================================---------------] 79% est: 4s 
 plot: [10,7] [==========================================================---------------] 80% est: 3s 
 plot: [10,8] [===========================================================--------------] 81% est: 3s 
 plot: [10,9] [===========================================================--------------] 81% est: 3s 
 plot: [10,10] [===========================================================-------------] 82% est: 3s 
 plot: [10,11] [============================================================------------] 83% est: 3s 
 plot: [10,12] [============================================================------------] 83% est: 3s 
 plot: [11,1] [=============================================================------------] 84% est: 3s 
 plot: [11,2] [==============================================================-----------] 85% est: 3s 
 plot: [11,3] [==============================================================-----------] 85% est: 3s 
 plot: [11,4] [===============================================================----------] 86% est: 2s 
 plot: [11,5] [===============================================================----------] 87% est: 2s 
 plot: [11,6] [================================================================---------] 88% est: 2s 
 plot: [11,7] [================================================================---------] 88% est: 2s 
 plot: [11,8] [=================================================================--------] 89% est: 2s 
 plot: [11,9] [=================================================================--------] 90% est: 2s 
 plot: [11,10] [=================================================================-------] 90% est: 2s 
 plot: [11,11] [==================================================================------] 91% est: 2s 
 plot: [11,12] [==================================================================------] 92% est: 1s 
 plot: [12,1] [===================================================================------] 92% est: 1s 
 plot: [12,2] [====================================================================-----] 93% est: 1s 
 plot: [12,3] [====================================================================-----] 94% est: 1s 
 plot: [12,4] [=====================================================================----] 94% est: 1s 
 plot: [12,5] [=====================================================================----] 95% est: 1s 
 plot: [12,6] [======================================================================---] 96% est: 1s 
 plot: [12,7] [======================================================================---] 97% est: 1s 
 plot: [12,8] [=======================================================================--] 97% est: 0s 
 plot: [12,9] [=======================================================================--] 98% est: 0s 
 plot: [12,10] [=======================================================================-] 99% est: 0s 
 plot: [12,11] [========================================================================] 99% est: 0s 
 plot: [12,12] [========================================================================]100% est: 0s 
                                                                                                      

Heat Maps

And finally, we’re going to do heat maps.

eyegaze_heat <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup, participant, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead"))) %>%
  ungroup() %>%
  mutate(maingroup = case_when(
    maingroup == "DeafEarly" ~ "Deaf Early",
    maingroup == "DeafLate" ~ "Deaf Late",
    maingroup == "HearingLate" ~ "Hearing Late",
    maingroup == "HearingNovice" ~ "Hearing Novice"
    ))
eyegaze_heat_all <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup,participant,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead"))) %>%
  ungroup() %>%
  mutate(maingroup = case_when(
    maingroup == "DeafEarly" ~ "Deaf Early",
    maingroup == "DeafLate" ~ "Deaf Late",
    maingroup == "HearingLate" ~ "Hearing Late",
    maingroup == "HearingNovice" ~ "Hearing Novice"
    ))
ggplot(eyegaze_heat, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.71), labels = percent, name = "looking time") +
  theme_bw() +
  theme(axis.text.x=element_text(angle=30,hjust=1),
        strip.text.x = element_text(size = 11, color = "black", face = "italic"), 
        strip.background = element_rect(colour = "white", fill = "white"),
        panel.grid.major = element_line(color = "white")) +
  facet_grid(. ~ direction) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map, by Direction") + 
  scale_y_discrete(expand=c(0,0)) +
  scale_x_discrete(expand = c(0,0))

ggplot(eyegaze_heat_all, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.71), labels = percent, name = "looking time") +
  theme_bw() +
  theme(axis.text.x=element_text(angle=30,hjust=1), 
  panel.grid.major = element_line(color = "white")) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map (Direction Collapsed)") +
  scale_y_discrete(expand=c(0,0)) +
  scale_x_discrete(expand = c(0,0))

Summary

Below are the p-values from the ANOVAs with 4 MainGroups. I never included Age as a covariate because it never improved the model. I included all ANOVAs for Gist and Lex Recall, and ANOVAs for any eye AOI or ratio was included only if either maingroup or direction was significant. Deafearly-Deaflate shows the LSD p-value for that comparison.

results1 <- structure(list(model = c("gist-maingroup-both", "gist-maingroup-fw", 
"gist-maingroup-rv", "lexrecall-maingroup-both", "lexrecall-maingroup-fw", 
"lexrecall-maingroup-rv", "mouth-maingroup-both", "upperchest-maingroup-both", 
"upperchest-maingroup-rv", "facechest-maingroup-both", "moutheye-maingroup-both"
), maingroup = c(0, 0, 0.01, 0, 0.04, 0.02, 0.06, 0, 0.01, 0.1, 
0.05), direction = c(0, NA, NA, 0, NA, NA, 0.06, 0.16, NA, 0.07, 
0.48), `deafearly-deaflate` = c(0.1, 0.69, 0.02, 0.11, 0.95, 
0.06, 0.38, 0.94, 0.52, 0.08, 0.68)), .Names = c("model", "maingroup", 
"direction", "deafearly-deaflate"), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -11L))
results1

And below are the p-values from the ANCOVAs with Hearing & AoASL. I included all ANCOVAs for Gist and Lex Recall, and ANCOVAs for any eye AOI or ratio was included only if any main factor was significant. LSD comparisons are not needed because there’s only 2 levels in each group!

results2 <- structure(list(model = c("gist-both", "gist-fw", "gist-rv", "lex-both", 
"lex-fw", "lex-rv", "forehead-fw", "mouth-both", "mouth-rv", 
"upperchest-both", "upperchest-rv", "facechest-both", "moutheye-both"
), hearing = c(0, 0.00, 0.01, 0.01, 0.22, 0.03, 0.06, 0.01, 
0.04, 0.01, 0.01, 0.35, 0.07), direction = c(0, NA, NA, 0, NA, 
NA, NA, 0.05, NA, 0.21, NA, 0.05, 0.52), aoasl = c(0.22, 0.77, 
0.19, 0.56, 0.58, 0.25, 0.08, 0.06, 0.12, 0.68, 0.95, 0.12, 0.44
), age = c(0.08, 0.01, 0.86, 0.09, 0.02, 0.7, 0.68, 0.28, 0.5, 
0.02, 0.08, 0.00, 0.21)), .Names = c("model", "hearing", "direction", 
"aoasl", "age"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-13L))
results2

Finally, the correlations for Deaf and Hearing separately are not significant. But there are significant correlations across all participants. I worry it is caused by HearingNovice, though…

results3 <- tribble(
  ~ metric, ~ AoASLcorrelationRvalue, ~ Pvalue,
  "gist-fw", -0.32, 0.019,
  "gist-rv", -0.39, 0.004,
  "lex-fw", -0.08, 0.567,
  "lex-rv", -0.34, 0.014
)
results3

Ternary Plots

Let’s make triangle plots. “What?” you say. Read on.

library(ggtern)
fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + stat_density_tern(geom='polygon', aes(fill=..level..), bins=4) + geom_point(color = "white", alpha = 0.5) + theme_bw()

fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + geom_confidence_tern(breaks = c(.5), color = "red") + geom_point() + theme_bw()

Rain’s Notes

About Adults:

-I think I want to write it up as an ANCOVA, with direction included. And LSD comparisons instead of Tukey. (I will do my own corrections) -You often have one liners summarizing results, in all tabs, those are nice, keep them coming. -(If you have reasons to present anything other than the ANCOVA, put that in your results tab)

I think if we do it this way then we get a really important story to tell: That the critical AoA cutoff is below 4 vs above 4 years of age (two groups 0-4 vs 4-13). This suggest early ASL is important.

LS0tCnRpdGxlOiAiVGhlIExhc3QgRGF0YSBBbmFseXNpcyB0byBSdWxlIFRoZW0gQWxsPyAoc3R1ZHkxYWR1bHRzKSIKYXV0aG9yOiAiQWRhbSBTdG9uZSwgUGhEIgpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlbS0lZC0lWSIpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBwYXBlcgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgpgYGB7ciBnbG9iYWxfb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UpCmBgYAoKIyBQdXR0aW5nIEl0IEFsbCBCYWNrIFRvZ2V0aGVyCgpUaHJvdWdob3V0IGFsbCB0aGUgZGF0YSBhbmFseXNpcyB3ZSd2ZSBkb25lLCB0aGUgZGF0YXNldHMgaGF2ZSBiZWNvbWUgbW9yZSBmcmFnbWVudGVkIC0gbGV4aWNhbCByZWNhbGwsIGdpc3QsIGFuZCBleWUgdHJhY2tpbmcgZGF0YXNldHMuIEkgd2FudCB0byBwdXQgdGhlbSBhbGwgdG9nZXRoZXIgaW4gb25lIHdob2xlIGRhdGFzZXQgYWdhaW4gc28gd2UgY2FuIHBlcmZvcm0gc29tZSBhbmFseXNlcyBtb3JlIGVmZmljaWVudGx5IChwYXJ0aWN1bGFybHkgY29ycmVsYXRpb25zKS4gVGhlIG9ubHkgdGhpbmcgSSBuZWVkIHRvIHJlbWVtYmVyIGlzIHdlJ2xsIGhhdmUgYSBuZXcgY29sdW1uIGNhbGxlZCBgZXllX2V4Y2x1ZGVgIGFuZCBpZiBpdCBpcyBzZXQgdG8gYFRSVUVgIGl0IG1lYW5zIHdlIGNhbid0IGluY2x1ZGUgdGhhdCByb3cgaW4gYW55IGFuYWx5c2lzIHJlbGF0aW5nIHRvIGV5ZSBnYXplICh1c3VhbGx5IGJlY2F1c2UgdGhhdCB0cmlhbCB3YXMgbGVzcyB0aGFuIDI1JSBsb29raW5nKS4gCgpgYGB7ciBzbWFzaCBkYXRhIHRvZ2V0aGVyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsbWU0KQpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGFncmljb2xhZSkgCmxpYnJhcnkoR0dhbGx5KQpsaWJyYXJ5KGV6KQoKIyBMb2FkIGxleCBhbmQgZXllIGRhdGEKY2xlYW5sZXhkYXRhIDwtIHJlYWRfY3N2KCJjbGVhbmRhdGEuY3N2IikgJT4lCiAgc2VsZWN0KC0oZm9yZWhlYWQ6dG90YWwpKQoKY2xlYW5leWVkYXRhIDwtIHJlYWRfY3N2KCJjbGVhbnBlcmNlbnRkYXRhLmNzdiIpICU+JQogIHNwcmVhZChhb2kscGVyY2VudCkgJT4lCiAgYWRkX2NvbHVtbihleWVfZXhjbHVkZSA9IEZBTFNFKQoKIyBXaGF0IHJvd3Mgd2VyZSByZW1vdmVkIGZyb20gdGhlIGV5ZSBkYXRhIGJhY2sgaW4gMDNleWVnYXplPyBMZXQncyBhZGQgYmFjayBpbgojIFdpdGggYSBuZXcgY29sdW1uIC0gZXllX2V4Y2x1ZGUKcmVtb3ZlZCA8LSBhbnRpX2pvaW4oY2xlYW5sZXhkYXRhLCBjbGVhbmV5ZWRhdGEpICU+JQogIGFkZF9jb2x1bW4oZXllX2V4Y2x1ZGUgPSBUUlVFKQpleWVsZXhkYXRhIDwtIGJpbmRfcm93cyhjbGVhbmV5ZWRhdGEsIHJlbW92ZWQpCgojIExvYWQgZ2lzdCBkYXRhCmdpc3QgPC0gcmVhZF9jc3YoJ2dpc3RfaW5kaXYuY3N2JywgY29sX3R5cGVzID0gY29scygKICBwYXJ0aWNpcGFudCA9IGNvbF9jaGFyYWN0ZXIoKSwKICBnaXN0LmZ3MSA9IGNvbF9pbnRlZ2VyKCksCiAgZ2lzdC5ydjIgPSBjb2xfaW50ZWdlcigpLAogIGdpc3QuZnczID0gY29sX2ludGVnZXIoKSwKICBnaXN0LnJ2NCA9IGNvbF9pbnRlZ2VyKCkKKSkgJT4lCiAgZ2F0aGVyKHZpZGVvLCBnaXN0LCBnaXN0LmZ3MTpnaXN0LnJ2NCkgJT4lCiAgbXV0YXRlKHZpZGVvID0gc3RyX3N1Yih2aWRlbyw2LDgpKQoKIyBQcmVzdG8sIG91ciBmdWxsIHJldW5pZmllZCBkYXRhc2V0IC0gJ2Z1bGxkYXRhJwojIEJ1dCBJIHdhbnQgdG8gcmVtb3ZlIGNvbHVtbnMgSSBkb24ndCB3YW50IGFueW1vcmUgYW5kIHdpbGwgcmVjYWxjdWxhdGUgbGF0ZXIKZnVsbGRhdGEgPC0gbGVmdF9qb2luKGV5ZWxleGRhdGEsIGdpc3QpICU+JQogIHNlbGVjdCgtbW91dGhleWUsIC1mYWNlY2hlc3QsIC1mYWNlLCAtY2hlc3QpCmBgYAoKIyBHcm91cCBDaGFuZ2VzIGFuZCBQYXJ0aWNpcGFudCBUYWJsZXMKCldlIGhhdmUgc29tZSBjaGFuZ2VzIHRvIG1ha2UgdG8gdGhlIGdyb3Vwcy4gRmlyc3QsIGZpeCBKb3NoIGFzIGxlYXJuaW5nIEFTTCB3aGVuIGhlIHdhcyA2LiBOZXh0LCBkcm9wIHRoZSBEZWFmTmF0aXZlIEdyb3VwIGFuZCByZWNsYXNzaWZ5IGFsbCB3aG8gbGVhcm5lZCBBU0wgPCAzLjkgYXMgRGVhZkVhcmx5IGFuZCBBU0wgPT4gNC4wIGFzIERlYWZMYXRlLiAKCmBgYHtyIGdyb3VwcyBhbmQgcGFydGljaXBhbnQgdGFibGVzfQojIENoYW5nZSBKb3NoJ3MgQW9BU0wgdG8gNgpmdWxsZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBtdXRhdGUoYW9hc2wgPSBhcy5kb3VibGUoYW9hc2wpKSAlPiUKICBtdXRhdGUoYW9hc2wgPSBjYXNlX3doZW4oCiAgICBwYXJ0aWNpcGFudCA9PSAiSm9zaCIgfiA2LAogICAgVFJVRSB+IGFvYXNsCiAgKSkKCiMgUmVjbGFzc2lmeSBHcm91cHMKZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgbXV0YXRlKG1haW5ncm91cCA9IGNhc2Vfd2hlbigKICAgIGhlYXJpbmcgPT0gIkRlYWYiICYgYW9hc2wgPCA0IH4gIkRlYWZFYXJseSIsCiAgICBoZWFyaW5nID09ICJEZWFmIiAmIGFvYXNsID49IDQgfiAiRGVhZkxhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTGF0ZUFTTCIgfiAiSGVhcmluZ0xhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTm92aWNlQVNMIiB+ICJIZWFyaW5nTm92aWNlIgogICkpCgojIENyZWF0ZSBQYXJ0aWNpcGFudCBEZW1vZ3JhcGhpY3MgVGFibGUKcGFydGljaXBhbnRfaW5mbyA8LSBmdWxsZGF0YSAlPiUKICBzZWxlY3QoLShhY2M6Z2lzdCkpICU+JQogIHNlbGVjdCgtKHZpZGVvOmRpcmVjdGlvbikpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIGdyb3VwX2J5KG1haW5ncm91cCkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCksCiAgICAgICAgICAgIGFnZV9tZWFuID0gbWVhbihhZ2UpLAogICAgICAgICAgICBhZ2Vfc2QgPSBzZChhZ2UpLAogICAgICAgICAgICBhb2FzbF9tZWFuID0gbWVhbihhb2FzbCksCiAgICAgICAgICAgIGFvYXNsX3NkID0gc2QoYW9hc2wpLAogICAgICAgICAgICBzaWdueXJzX21lYW4gPSBtZWFuKHNpZ255cnMpLAogICAgICAgICAgICBzaWdueXJzX3NkID0gc2Qoc2lnbnlycyksCiAgICAgICAgICAgIHNlbGZyYXRlX21lYW4gPSBtZWFuKHNlbGZyYXRlKSwKICAgICAgICAgICAgc2VsZnJhdGVfc2QgPSBzZChzZWxmcmF0ZSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGVfaWYoaXMuZG91YmxlLCBmdW5zKHJvdW5kKC4sIDIpKSkgJT4lCiAgbXV0YXRlKGFnZSA9IHBhc3RlKGFnZV9tZWFuLCAiwrEiLCBhZ2Vfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIGFvYXNsID0gcGFzdGUoYW9hc2xfbWVhbiwgIsKxIiwgYW9hc2xfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIHNpZ255cnMgPSBwYXN0ZShzaWdueXJzX21lYW4sICLCsSIsIHNpZ255cnNfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIHNlbGZyYXRlID0gcGFzdGUoc2VsZnJhdGVfbWVhbiwgIsKxIiwgc2VsZnJhdGVfc2QsIHNlcCA9ICIgIikpICU+JQogIHNlbGVjdCgtKGFnZV9tZWFuOnNlbGZyYXRlX3NkKSkKCnBhcnRpY2lwYW50X2luZm8Kd3JpdGVfY3N2KGZ1bGxkYXRhLCAiZmluYWxkYXRhc2V0LmNzdiIpCgpkYXRhX2xvd2FvaSA8LSBmdWxsZGF0YSAlPiUgc2VsZWN0KHBhcnRpY2lwYW50LCBzdG9yeSwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lIHNlbGVjdCgtZXllcywgLW1vdXRoLCAtY2hpbikgJT4lIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpCmRhdGFfbG93YW9pJHBlcmNlbnRbaXMubmEoZGF0YV9sb3dhb2kkcGVyY2VudCldIDwtIDAKbWVhbihkYXRhX2xvd2FvaSRwZXJjZW50LCBuYS5ybT1UUlVFKQpzZChkYXRhX2xvd2FvaSRwZXJjZW50LCBuYS5ybT1UUlVFKQpgYGAKIyMgUGFydGljaXBhbnQgQU5PVkFzIAoKQmVsb3cgYXJlIHRoZSBBTk9WQSBvdXRwdXRzIGZvciBwYXJ0aWNpcGFudCBkZW1vZ3JhcGhpY3MsIGFuZCBMU0RzIGZvciBlYWNoLiAKClBhcnRpY2lwYW50cycgYWdlCmBgYHtyIHN1YmplY3QgYW5vdmEgYWdlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIE1ha2UgdGhlIHBhcnRpY2lwYW50IGRhdGEgZnJhbWUKcF9hbm92YXMgPC0gZnVsbGRhdGEgJT4lCiAgc2VsZWN0KC0oYWNjOmdpc3QpKSAlPiUKICBzZWxlY3QoLSh2aWRlbzpkaXJlY3Rpb24pKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHNlbGVjdChtYWluZ3JvdXA6YW9hc2wpCgojIEFnZSBBTk9WQQpwX2FnZSA8LSBhb3YoYWdlIH4gbWFpbmdyb3VwLCBkYXRhID0gcF9hbm92YXMpCnN1bW1hcnkocF9hZ2UpCnBfYWdlX2xzZCA8LSBMU0QudGVzdChwX2FnZSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpJGNvbXBhcmlzb24KcF9hZ2VfbHNkCmBgYAoKClBhcnRpY2lwYW50cycgQW9BU0wKYGBge3Igc3ViamVjdCBhbm92YSBhb2FzbCwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBBb0FTTCBBTk9WQQpwX2FvYXNsIDwtIGFvdihhb2FzbCB+IG1haW5ncm91cCwgZGF0YSA9IHBfYW5vdmFzKQpzdW1tYXJ5KHBfYW9hc2wpCnBfYW9hc2xfbHNkIDwtIExTRC50ZXN0KHBfYW9hc2wsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKSRjb21wYXJpc29uCnBfYW9hc2xfbHNkCmBgYAoKUGFydGljaXBhbnRzJyBTaWduIFlycwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNpZ255cnMsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgU2lnbnlycyBBTk9WQQpwX3NpZ255cnMgPC0gYW92KHNpZ255cnMgfiBtYWluZ3JvdXAsIGRhdGEgPSBwX2Fub3ZhcykKc3VtbWFyeShwX3NpZ255cnMpCnBfc2lnbnlyc19sc2QgPC0gTFNELnRlc3QocF9zaWdueXJzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkkY29tcGFyaXNvbgpwX3NpZ255cnNfbHNkCmBgYAoKUGFydGljaXBhbnRzJyBTZWxmLVJhdGluZwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNlbGZyYXRlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFNlbGZyYXRlIEFOT1ZBCnBfc2VsZnJhdGUgPC0gYW92KHNlbGZyYXRlIH4gbWFpbmdyb3VwLCBkYXRhID0gcF9hbm92YXMpCnN1bW1hcnkocF9zZWxmcmF0ZSkKcF9zZWxmcmF0ZV9sc2QgPC0gTFNELnRlc3QocF9zZWxmcmF0ZSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpJGNvbXBhcmlzb24KcF9zZWxmcmF0ZV9sc2QKYGBgCgojIEdpc3QgJiBMZXhpY2FsIFJlY2FsbCBEYXRhCgojIyBUYWJsZXMgJiBDaGFydHMKCkxldCdzIGdlbmVyYXRlIGEgdGFibGUgZm9yIGxleGljYWwgcmVjYWxsIGFuZCBnaXN0IGZvciBmb3J3YXJkIHZzLiByZXZlcnNlZCBzdG9yaWVzLiAKCmBgYHtyIGxleCAmIGdpc3QgdGFibGV9CmxleGdpc3RfaW5mbyA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGxleF9tZWFuID0gbWVhbihhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGxleF9zZCA9IHNkKGFjYywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgZ2lzdF9tZWFuID0gbWVhbihnaXN0KSwKICAgICAgICAgICAgZ2lzdF9zZCA9IHNkKGdpc3QpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlX2lmKGlzLmRvdWJsZSwgZnVucyhyb3VuZCguLCAyKSkpICU+JSAKICBtdXRhdGUobGV4ID0gcGFzdGUobGV4X21lYW4sICLCsSIsIGxleF9zZCwgc2VwID0gIiAiKSwKICAgICAgICAgZ2lzdCA9IHBhc3RlKGdpc3RfbWVhbiwgIsKxIiwgZ2lzdF9zZCwgc2VwID0gIiAiKSkgJT4lCiAgc2VsZWN0KC0obGV4X21lYW46Z2lzdF9zZCkpICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCBsZXg6Z2lzdCkgJT4lCiAgdW5pdGUoIm1ldHJpYyIsIGMobWV0cmljLCBkaXJlY3Rpb24pLCBzZXAgPSAiXyIpICU+JQogIHNwcmVhZChtZXRyaWMsIHZhbHVlKSAlPiUKICBwcmludCgpCmBgYAoKQW5kIHRoZW4gYmFyIGNoYXJ0cyB0b28gYWZ0ZXIgdGhhdCB3aXRoIGVycm9yIGJhcnMuIAoKYGBge3IgbGV4IGFuZCBnaXN0IGJhciBjaGFydHN9CiMgR2lzdCBiYXIgY2hhcnQKZ2lzdF9iYXIgPC0gZnVsbGRhdGEgJT4lIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwLCBkaXJlY3Rpb24sIGdpc3QpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGdpc3QgPSBtZWFuKGdpc3QpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGdpc3QpLAogICAgICAgICAgICBzZCA9IHNkKGdpc3QpLAogICAgICAgICAgICBjb3VudCA9IG4oKSwKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KGNvdW50KSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShtYWluZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBtYWluZ3JvdXAgPT0gIkRlYWZFYXJseSIgfiAiRGVhZiBFYXJseSIsCiAgICBtYWluZ3JvdXAgPT0gIkRlYWZMYXRlIiB+ICJEZWFmIExhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTGF0ZSIgfiAiSGVhcmluZyBMYXRlIiwKICAgIG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIgfiAiSGVhcmluZyBOb3ZpY2UiCiAgICApKQoKZ2dwbG90KGdpc3RfYmFyLCBhZXMoeCA9IG1haW5ncm91cCwgeSA9IG1lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJHaXN0IiwgeCA9ICIiLCB5ID0gIm1lYW4gZ2lzdCBhY2N1cmFjeSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCwgbGltaXRzID0gYygwLDEpKSArIHRoZW1lX2J3KCkKCiMgTGV4IGJhciBjaGFydApsZXhfYmFyIDwtIGZ1bGxkYXRhICU+JSBzZWxlY3QocGFydGljaXBhbnQsIG1haW5ncm91cCwgZGlyZWN0aW9uLCBhY2MpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGFjYyA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgc2QgPSBzZChhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGNvdW50ID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKG1haW5ncm91cCA9IGNhc2Vfd2hlbigKICAgIG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IiB+ICJEZWFmIEVhcmx5IiwKICAgIG1haW5ncm91cCA9PSAiRGVhZkxhdGUiIH4gIkRlYWYgTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdMYXRlIiB+ICJIZWFyaW5nIExhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTm92aWNlIiB+ICJIZWFyaW5nIE5vdmljZSIKICAgICkpCgpnZ3Bsb3QobGV4X2JhciwgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gZGlyZWN0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW4tc2UsIHltYXggPSBtZWFuK3NlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCB3aWR0aCA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiTGV4aWNhbCBSZWNhbGwiLCB4ID0gIiIsIHkgPSAibWVhbiBsZXhpY2FsIHJlY2FsbCBhY2N1cmFjeSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCwgbGltaXRzID0gYygwLDEpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjUsIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLjUsMSkpICsgdGhlbWVfYncoKQpgYGAKCkFuZCBsZXQncyBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgcmVkdWN0aW9uIGluIHNjb3JlIGR1ZSB0byByZXZlcnNhbCBmaXJzdCBpcyBsZXggcmVjYWxsLCB0aGVuIGdpc3QuCgpgYGB7cn0KcmV2ZXJzYWxfbGV4IDwtIGZ1bGxkYXRhICU+JQogIGdyb3VwX2J5KGlkLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShsZXhfbWVhbiA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBzcHJlYWQoZGlyZWN0aW9uLCBsZXhfbWVhbikgJT4lCiAgZ3JvdXBfYnkoaWQpICU+JQogIG11dGF0ZShyZXZlcnNhbCA9IGZvcndhcmQgLSByZXZlcnNlZCkgJT4lCiAgdW5ncm91cCgpCgpwYXN0ZSgibGV4IG1lYW4iLCBtZWFuKHJldmVyc2FsX2xleCRyZXZlcnNhbCkpCnBhc3RlKCJsZXggc2QiLCBzZChyZXZlcnNhbF9sZXgkcmV2ZXJzYWwpKQoKcmV2ZXJzYWxfZ2lzdCA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShpZCwgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoZ2lzdF9tZWFuID0gbWVhbihnaXN0LCBuYS5ybSA9IFRSVUUpKSAlPiUKICBzcHJlYWQoZGlyZWN0aW9uLCBnaXN0X21lYW4pICU+JQogIGdyb3VwX2J5KGlkKSAlPiUKICBtdXRhdGUocmV2ZXJzYWwgPSBmb3J3YXJkIC0gcmV2ZXJzZWQpICU+JQogIHVuZ3JvdXAoKQoKcGFzdGUoImdpc3QgbWVhbiIsIG1lYW4ocmV2ZXJzYWxfZ2lzdCRyZXZlcnNhbCkpCnBhc3RlKCJnaXN0IHNkIiwgc2QocmV2ZXJzYWxfZ2lzdCRyZXZlcnNhbCkpCgoKYGBgCgoKIyMgQU5PVkEgUGxhbgpOZXh0LCB3ZSdyZSBnb2luZyB0byBkbyBBTk9WQXMuIFdlJ2xsIGFsd2F5cyBkbyBpdCBpbiB0aGlzIG9yZGVyLgoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbgoyLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBGb3J3YXJkIG9ubHkKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5IAoKKEkgYWxzbyByYW4gQU5DT1ZBcyBiZWZvcmUgYnV0IG5vdyBoYXZlIHRha2VuIHRoZW0gb3V0Li4udGhleSBhcmUgYmVsb3c6ICg0KSBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UsICg1KSBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBGb3J3YXJkIG9ubHksICg2KSBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBSZXZlcnNlIG9ubHkuKSAKCkkgZGlkIG5vdCBpbmNsdWRlIEFnZSBhcyBhIGNvdmFyaWF0ZSBpbiB0aGUgZmlyc3QgMyBBTk9WQXMgYmVjYXVzZSB0aGV5IGRpZCBub3QgYWRkIHRvIG9yIGNoYW5nZSB0aGUgbW9kZWwgaW4gYW55IHNpZ25pZmljYW50IHdheS4gCgojIyBHaXN0IEFOT1ZBcwoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGdpc3QgYW5vdmExLCBlY2hvPVRSVUUsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBGaXJzdCBsZXQncyBtYWtlIHRoZSBwYXJ0aWNpcGFudC1sZXZlbCBkYXRhc2V0IHdpdGggd2hpY2ggd2UnbGwgZG8gb3VyIEFOQ09WQXMuIApwYXJ0aWNpcGFudF9kYXRhIDwtIGZ1bGxkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgbXV0YXRlKGdpc3QgPSBtZWFuKGdpc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGFjYyA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KGlkLCBwYXJ0aWNpcGFudCwgaGVhcmluZywgbWFpbmdyb3VwLCBkaXJlY3Rpb24sIGFnZSwgYW9hc2wsIGFjYywgZ2lzdCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBtdXRhdGUoaWQgPSBmYWN0b3IoaWQpLAogICAgICAgICBwYXJ0aWNpcGFudCA9IGZhY3RvcihwYXJ0aWNpcGFudCksCiAgICAgICAgIGhlYXJpbmcgPSBmYWN0b3IoaGVhcmluZyksCiAgICAgICAgIG1haW5ncm91cCA9IGZhY3RvcihtYWluZ3JvdXApLAogICAgICAgICBkaXJlY3Rpb24gPSBmYWN0b3IoZGlyZWN0aW9uKSkKCiMgIyBHaXN0IEFOT1ZBIDEKIyBnaXN0X2FvdjEgPC0gYW92KGdpc3QgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBwYXJ0aWNpcGFudF9kYXRhKQojIHN1bW1hcnkoZ2lzdF9hb3YxKQojIGdpc3RfbHNkMSA8LSBMU0QudGVzdChnaXN0X2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGdpc3RfbHNkMSRjb21wYXJpc29uCgojIEdpc3QgRVogQU5PVkEKZXpBTk9WQSgKICBkYXRhID0gcGFydGljaXBhbnRfZGF0YSwKICBkdiA9IGdpc3QsCiAgd2lkID0gaWQsCiAgd2l0aGluID0gZGlyZWN0aW9uLAogIGJldHdlZW4gPSBtYWluZ3JvdXAsCiAgdHlwZSA9IDMKKVsiQU5PVkEiXQpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4gKkluIHRoZSBjb2RlIGlzIGEgS3J1c2thbC1XYWxsaXMgdGVzdC4gQW5kIENoaS1TcSB0b28uKgoKYGBge3IgZ2lzdCBhbm92YTIsIGVjaG89VFJVRSwgcmVzdWx0cz0gJ21hcmt1cCd9CiMgIyBHaXN0IEFOT1ZBIDIKIyBnaXN0X2FvdjIgPC0gYW92KGdpc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCiMgc3VtbWFyeShnaXN0X2FvdjIpCiMgZ2lzdF9sc2QyIDwtIExTRC50ZXN0KGdpc3RfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgZ2lzdF9sc2QyJGNvbXBhcmlzb24KCmV6QU5PVkEoCiAgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSwKICBkdiA9IGdpc3QsCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCgojICMgS1cgTm9uLXBhcmFtZXRyaWMgdGVzdCAobGlrZSBvbmUtd2F5IEFOT1ZBKQojIGtydXNrYWwudGVzdChnaXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gYXMubWF0cml4KGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkpCiMgCiMgIyBDaGkgU3EKIyBnaXN0X2NoaXNxX2Z3IDwtIHBhcnRpY2lwYW50X2RhdGEgJT4lCiMgICB1bmdyb3VwKCkgJT4lCiMgICBmaWx0ZXIoZGlyZWN0aW9uID09ICJmb3J3YXJkIikgJT4lCiMgICBzZWxlY3QobWFpbmdyb3VwLCBnaXN0KSAlPiUKIyAgIGdyb3VwX2J5KG1haW5ncm91cCwgZ2lzdCkgJT4lCiMgICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQojICAgc3ByZWFkKGdpc3QsIGNvdW50KSAlPiUKIyAgIHJlbmFtZShub25lID0gIjAiLAojICAgICAgICAgIG9uZSA9ICIwLjUiLAojICAgICAgICAgIGJvdGggPSAiMSIpCiMgCiMgZ2lzdF9jaGlzcV9md1tpcy5uYShnaXN0X2NoaXNxX2Z3KV0gPC0gMEwKIyBnaXN0X2NoaXNxX2Z3IDwtIGNiaW5kKGdpc3RfY2hpc3FfZndbLCJub25lIl0sIGdpc3RfY2hpc3FfZndbLCJvbmUiXSwgZ2lzdF9jaGlzcV9md1ssImJvdGgiXSkKIyBjaGlzcS50ZXN0KGdpc3RfY2hpc3FfZncpCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAqSW4gdGhlIGNvZGUgaXMgYSBLcnVza2FsLVdhbGxpcyB0ZXN0LiBBbmQgQ2hpLVNxIHRvby4qCgpgYGB7ciBnaXN0IGFub3ZhMywgZWNobz1UUlVFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgIyBHaXN0IEFOT1ZBIDMKIyBnaXN0X2FvdjMgPC0gYW92KGdpc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQojIHN1bW1hcnkoZ2lzdF9hb3YzKQojIGdpc3RfbHNkMyA8LSBMU0QudGVzdChnaXN0X2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGdpc3RfbHNkMyRjb21wYXJpc29uIAoKZXpBTk9WQSgKICBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSwKICBkdiA9IGdpc3QsCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCgojICMgS1cgTm9uLXBhcmFtZXRyaWMgdGVzdCAobGlrZSBvbmUtd2F5IEFOT1ZBKQojIGtydXNrYWwudGVzdChnaXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gYXMubWF0cml4KGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpKQojIAojICMgQ2hpIFNxCiMgZ2lzdF9jaGlzcV9ydiA8LSBwYXJ0aWNpcGFudF9kYXRhICU+JQojICAgdW5ncm91cCgpICU+JQojICAgZmlsdGVyKGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSAlPiUKIyAgIHNlbGVjdChtYWluZ3JvdXAsIGdpc3QpICU+JQojICAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnaXN0KSAlPiUKIyAgIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiMgICBzcHJlYWQoZ2lzdCwgY291bnQpICU+JQojICAgcmVuYW1lKG5vbmUgPSAiMCIsCiMgICAgICAgICAgb25lID0gIjAuNSIsCiMgICAgICAgICAgYm90aCA9ICIxIikKIyAKIyBnaXN0X2NoaXNxX3J2W2lzLm5hKGdpc3RfY2hpc3FfcnYpXSA8LSAwTAojIGdpc3RfY2hpc3FfcnYgPC0gY2JpbmQoZ2lzdF9jaGlzcV9ydlssIm5vbmUiXSwgZ2lzdF9jaGlzcV9ydlssIm9uZSJdLCBnaXN0X2NoaXNxX3J2WywiYm90aCJdKQojIGNoaXNxLnRlc3QoZ2lzdF9jaGlzcV9ydikKYGBgCgojIyBMZXhpY2FsIFJlY2FsbCBBTk9WQXMKCjEuIEFOT1ZBIHdpdGggZmFjdG9ycyBNYWluR3JvdXAgJiBEaXJlY3Rpb24uCgpgYGB7ciBhY2MgYW5vdmExLCBlY2hvPVRSVUUsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyAjIExleGljYWwgUmVjYWxsIEFOT1ZBIDEKIyBhY2NfYW92MSA8LSBhb3YoYWNjIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gcGFydGljaXBhbnRfZGF0YSkKIyBzdW1tYXJ5KGFjY19hb3YxKQojIGFjY19sc2QxIDwtIExTRC50ZXN0KGFjY19hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBhY2NfbHNkMSRjb21wYXJpc29uCgplekFOT1ZBKAogIGRhdGEgPSBwYXJ0aWNpcGFudF9kYXRhLAogIGR2ID0gYWNjLAogIHdpZCA9IGlkLAogIHdpdGhpbiA9IGRpcmVjdGlvbiwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgoyLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBGb3J3YXJkIG9ubHkuCgpgYGB7ciBhY2MgYW5vdmEyLCBlY2hvPVRSVUUsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyAjIExleGljYWwgUmVjYWxsIEFOT1ZBIDIKIyBhY2NfYW92MiA8LSBhb3YoYWNjIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQojIHN1bW1hcnkoYWNjX2FvdjIpCiMgYWNjX2xzZDIgPC0gTFNELnRlc3QoYWNjX2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGFjY19sc2QyJGNvbXBhcmlzb24KCmV6QU5PVkEoCiAgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSwKICBkdiA9IGFjYywKICB3aWQgPSBpZCwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgozLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgYWNjIGFub3ZhMywgZWNobz1UUlVFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgIyBMZXhpY2FsIFJlY2FsbCBBTk9WQSAzCiMgYWNjX2FvdjMgPC0gYW92KGFjYyB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCiMgc3VtbWFyeShhY2NfYW92MykKIyBhY2NfbHNkMyA8LSBMU0QudGVzdChhY2NfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgYWNjX2xzZDMkY29tcGFyaXNvbgoKZXpBTk9WQSgKICBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSwKICBkdiA9IGFjYywKICB3aWQgPSBpZCwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgojIEFvQSBDb3JyZWxhdGlvbnMKCk5leHQsIHdlIHdhbnQgdG8gbG9vayBhdCBjb3JyZWxhdGlvbnMgYmV0d2VlbiBBb0EgYW5kIEdpc3QsIGFuZCBiZXR3ZW4gQW9BIGFuZCBMZXhpY2FsIFJlY2FsbC4gUmFpbiBhc2tlZCBmb3IgZm9yd2FyZCBhbmQgcmV2ZXJzZWQgc2VwYXJhdGVseSAoMSkgZGVhZiBvbmx5LCAoMikgaGVhcmluZyBvbmx5LCBhbmQgKDMpIGJvdGguIExldCdzIG1ha2UgaXQgd29yay4gCgpgYGB7ciByZXBhY2thZ2UgZGF0YSBmb3IgY29ycmVsYXRpb25zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExldCdzIG1ha2UgcGFydGljaXBhbnQtbGV2ZWwgZGF0YSwgYW5kIGhhdmUgZm9yd2FyZC9yZXZlcnNlZCBpbiBzZXBhcmF0ZSBjb2x1bW5zCmxleGdpc3RfZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24pICU+JQogIG11dGF0ZShnaXN0ID0gbWVhbihnaXN0LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBsZXggPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdChtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBoZWFyaW5nLCBkaXJlY3Rpb24sIGFvYXNsLCBzaWdueXJzLCBhZ2UsIGdpc3QsIGxleCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgZ2lzdDpsZXgpICU+JQogIHVuaXRlKG1ldHJpY3ZhbHVlLCBjKG1ldHJpYywgZGlyZWN0aW9uKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQobWV0cmljdmFsdWUsIHZhbHVlKSAlPiUKICBzZWxlY3QoLXBhcnRpY2lwYW50LCAtbWFpbmdyb3VwKQoKbGV4Z2lzdF9kZWFmIDwtIGxleGdpc3RfZGF0YSAlPiUgZmlsdGVyKGhlYXJpbmcgPT0gIkRlYWYiKSAlPiUgc2VsZWN0KC1oZWFyaW5nKQpsZXhnaXN0X2hlYXJpbmcgPC0gbGV4Z2lzdF9kYXRhICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiSGVhcmluZyIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmxleGdpc3RfYWxsIDwtIGxleGdpc3RfZGF0YSAlPiUgc2VsZWN0KC1oZWFyaW5nKQoKIyBMb2FkIGF3ZXNvbWUgZnVuY3Rpb24gdG8gbWFrZSBjb3JyZWxhdGlvbiB0YWJsZXMgd2l0aCBzdGFycyBmb3Igc2lnbmlmaWNhbmNlCiMgRnJvbTogaHR0cHM6Ly9teW93ZWx0LmJsb2dzcG90LmNvLnVrLzIwMDgvMDQvYmVhdXRpZnVsLWNvcnJlbGF0aW9uLXRhYmxlcy1pbi1yLmh0bWwKY29yc3RhcnNsIDwtIGZ1bmN0aW9uKHgpeyAKcmVxdWlyZShIbWlzYykgCnggPC0gYXMubWF0cml4KHgpIApSIDwtIEhtaXNjOjpyY29ycih4KSRyIApwIDwtIEhtaXNjOjpyY29ycih4KSRQIAojIyBkZWZpbmUgbm90aW9ucyBmb3Igc2lnbmlmaWNhbmNlIGxldmVsczsgc3BhY2luZyBpcyBpbXBvcnRhbnQuCm15c3RhcnMgPC0gaWZlbHNlKHAgPCAuMDAxLCAiKioqIiwgaWZlbHNlKHAgPCAuMDEsICIqKiAiLCBpZmVsc2UocCA8IC4wNSwgIiogIiwgIiAiKSkpCiMjIHRydW5jdHVhdGUgdGhlIG1hdHJpeCB0aGF0IGhvbGRzIHRoZSBjb3JyZWxhdGlvbnMgdG8gdHdvIGRlY2ltYWwKUiA8LSBmb3JtYXQocm91bmQoY2JpbmQocmVwKC0xLjExLCBuY29sKHgpKSwgUiksIDIpKVssLTFdIAojIyBidWlsZCBhIG5ldyBtYXRyaXggdGhhdCBpbmNsdWRlcyB0aGUgY29ycmVsYXRpb25zIHdpdGggdGhlaXIgYXByb3ByaWF0ZSBzdGFycyAKUm5ldyA8LSBtYXRyaXgocGFzdGUoUiwgbXlzdGFycywgc2VwPSIiKSwgbmNvbD1uY29sKHgpKSAKZGlhZyhSbmV3KSA8LSBwYXN0ZShkaWFnKFIpLCAiICIsIHNlcD0iIikgCnJvd25hbWVzKFJuZXcpIDwtIGNvbG5hbWVzKHgpIApjb2xuYW1lcyhSbmV3KSA8LSBwYXN0ZShjb2xuYW1lcyh4KSwgIiIsIHNlcD0iIikgCiMjIHJlbW92ZSB1cHBlciB0cmlhbmdsZQpSbmV3IDwtIGFzLm1hdHJpeChSbmV3KQpSbmV3W3VwcGVyLnRyaShSbmV3LCBkaWFnID0gVFJVRSldIDwtICIiClJuZXcgPC0gYXMuZGF0YS5mcmFtZShSbmV3KSAKIyMgcmVtb3ZlIGxhc3QgY29sdW1uIGFuZCByZXR1cm4gdGhlIG1hdHJpeCAod2hpY2ggaXMgbm93IGEgZGF0YSBmcmFtZSkKUm5ldyA8LSBjYmluZChSbmV3WzE6bGVuZ3RoKFJuZXcpLTFdKQpyZXR1cm4oUm5ldykgCn0KCiMgQ29ycmVsYXRpb25zIGZvciBEZWFmCnByaW50KCJERUFGIENvcnJlbGF0aW9ucyAtIFBlYXJzb24ncyByIikKI2NvcnN0YXJzbChsZXhnaXN0X2RlYWYpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9kZWFmKSkkcgpwcmludCgiREVBRiBDb3JyZWxhdGlvbnMgLSBQLXZhbHVlcyIpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9kZWFmKSkkUApjYXQocGFzdGUoIiIsIlxuIiwiIikpCgojIENvcnJlbGF0aW9ucyBmb3IgSGVhcmluZwpwcmludCgiSEVBUklORyBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9oZWFyaW5nKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfaGVhcmluZykpJHIKcHJpbnQoIkhFQVJJTkcgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfaGVhcmluZykpJFAKY2F0KHBhc3RlKCIiLCJcbiIsIiIpKQoKIyBDb3JyZWxhdGlvbnMgZm9yIEFsbApwcmludCgiQUxMIENvcnJlbGF0aW9ucyAtIFBlYXJzb24ncyByIikKI2NvcnN0YXJzbChsZXhnaXN0X2FsbCkKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChsZXhnaXN0X2FsbCkpJHIKcHJpbnQoIkFMTCBDb3JyZWxhdGlvbnMgLSBQLXZhbHVlcyIpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9hbGwpKSRQCgpgYGAKCkknbSBhbHNvIGluY2x1ZGluZyBuaWNlbHkgZm9ybWF0dGVkIHRhYmxlcyB3aXRoICoqKiBpbmRpY2F0b3JzIG9mIHNpZ25pZmljYW5jZSBmb3IgcXVpY2sgcmVmZXJlbmNpbmcuIE9yZGVyOiBEZWFmLCBIZWFyaW5nLCBBbGwuIAoKYGBge3IgcHJldHR5IGNvcnJlbGF0aW9uc30KY29yc3RhcnNsKGxleGdpc3RfZGVhZikKY29yc3RhcnNsKGxleGdpc3RfaGVhcmluZykKY29yc3RhcnNsKGxleGdpc3RfYWxsKQpgYGAKCiMjIFNjYXR0ZXJwbG90IG9mIENvcnJlbGF0aW9ucwpMZXQncyB2aXN1YWxpemUgd2hhdCdzIGhhcHBlbmluZyB3aXRoIHRoZSBjb3JyZWxhdGlvbnMgaGVyZS4gCmBgYHtyIGNvcnJlbGF0aW9uIGNoYXJ0cywgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3BhaXJzKGxleGdpc3RfZGF0YSwgY29sdW1ucyA9IGMoMjo4KSwgYWVzKGNvbG9yID0gaGVhcmluZykpCmBgYAoKCiMgRXllIEdhemUgRGF0YQoKTm93IGV5ZSBnYXplIGRhdGEuIEJveHBsb3RzIGZpcnN0LiBBbHNvIGhlcmUsIHdlJ3JlIHJlbmFtaW5nICJjaGluIiB0byAibmVjayIgYmVjYXVzZSB0aGF0J3Mgd2hhdCBpdCBhY3R1YWxseSBpcyEgQnV0IHdlIGFsc28gaGF2ZSB0byBmaXggYWxsIE5BJ3MgaW4gdGhlIHBlcmNlbnRhZ2VzIHRvIHplcm9zLCBiZWN1YXNlIHRoYXQncyB3aGF0IHRoZXkgYWN0dWFsbHkgYXJlLiAKYGBge3IgZXllIGdhemUgYm94cGxvdH0KIyByZW5hbWUgY2hpbiB0byBuZWNrCmZ1bGxkYXRhIDwtIGZ1bGxkYXRhICU+JQogIHJlbmFtZShuZWNrID0gY2hpbikgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkKCiMgRml4IGFsbCBOQSdzIGluIFBlcmNlbnQgY29sdW1uIHRvIDAKZml4cGVyY2VudCA8LSBmdWxsZGF0YSRwZXJjZW50CmZ1bGxkYXRhJHBlcmNlbnQgPC0gY29hbGVzY2UoZml4cGVyY2VudCwgMCkKZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgc3ByZWFkKGFvaSwgcGVyY2VudCkKCmZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGRpcmVjdGlvbiwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYW9pLCB5ID0gcGVyY2VudCwgZmlsbCA9IGRpcmVjdGlvbikpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgpCdXQgbGV0J3MgdHJ5IGVycm9yIGNoYXJ0cyB0b28hIEluc3RlYWQgb2YgYm94cGxvdHMuCgpgYGB7ciBleWUgZ2F6ZSBlcnJvciBiYXIgY2hhcnR9CmZ1bGxkYXRhX2Vycm9yIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ3JvdXBfYnkoaWQsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ3JvdXBfYnkoZGlyZWN0aW9uLCBhb2kpICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihwZXJjZW50LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBzZCA9IHNkKHBlcmNlbnQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGNvdW50ID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKQpmdWxsZGF0YV9lcnJvciRhb2kgPC0gZmN0X3JlbGV2ZWwoZnVsbGRhdGFfZXJyb3IkYW9pLCBjKCJmb3JlaGVhZCIsImV5ZXMiLCJtb3V0aCIsIm5lY2siLCJ1cHBlcmNoZXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWlkY2hlc3QiLCJsb3dlcmNoZXN0IiwiYmVsbHkiLCJsZWZ0IiwicmlnaHQiKSkKCmZ1bGxkYXRhX2Vycm9yICU+JQogIGdncGxvdChhZXMoeCA9IGFvaSwgeSA9IG1lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJFeWUgR2F6ZSBCZWhhdmlvciIsIHggPSAiIiwgeSA9ICJsb29raW5nIHRpbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQsIGxpbWl0cyA9IGMoMCwuNzApKSArIAogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkKYGBgCgpBbmQgYSB0YWJsZSBvZiBleWUgZ2F6ZSByZXN1bHRzIHRvbwoKYGBge3IgZXllIGdhemUgZXJyb3IgdGFibGV9CmZ1bGxkYXRhX2dhemV0YWJsZSA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdyb3VwX2J5KGlkLCBtYWluZ3JvdXAsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24sIGFvaSkgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHNkID0gc2QocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgbXV0YXRlKG1lYW4gPSByb3VuZChtZWFuKjEwMCwxKSwKICAgICAgICAgc2QgPSByb3VuZChzZCoxMDAsMSkpICU+JQogIG11dGF0ZSh2YWx1ZSA9IHBhc3RlKG1lYW4sIHNkLCBzZXAgPSAiIMKxICIpKSAlPiUKICBtdXRhdGUodmFsdWUgPSBwYXN0ZSh2YWx1ZSwgIiUiLCBzZXAgPSAiIikpCgpmdWxsZGF0YV9nYXpldGFibGUkYW9pIDwtIGZjdF9yZWxldmVsKGZ1bGxkYXRhX2dhemV0YWJsZSRhb2ksIGMoImZvcmVoZWFkIiwiZXllcyIsIm1vdXRoIiwibmVjayIsInVwcGVyY2hlc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtaWRjaGVzdCIsImxvd2VyY2hlc3QiLCJiZWxseSIsImxlZnQiLCJyaWdodCIpKQoKZnVsbGRhdGFfZ2F6ZXRhYmxlICU+JSAKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KC1tZWFuLCAtc2QpICU+JSAKICBzcHJlYWQoYW9pLCB2YWx1ZSkKCmZ1bGxkYXRhX3RvdGFsIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ3JvdXBfYnkoYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgc3ByZWFkKGFvaSwgcGVyY2VudCkKCiNzdW0oZnVsbGRhdGFfdG90YWwkZXllcywgZnVsbGRhdGFfdG90YWwkbW91dGgsIGZ1bGxkYXRhX3RvdGFsJG5lY2spCiNmdWxsZGF0YV90b3RhbCRsZWZ0CiNmdWxsZGF0YV90b3RhbCRyaWdodApgYGAKIyMgQmlnIFRocmVlLVdheSBBTk9WQQpOb3cgd2UncmUgZ29pbmcgdG8gdHJ5IGEgdGhyZWUtd2F5IEdyb3VwIHggRGlyZWN0aW9uIHggQU9JIEFOT1ZBIHdpdGggdGhlIHRvcCAzIEFPSXMgKEV5ZXMsIE1vdXRoLCBOZWNrKQoKYGBge3IgYmlnIGFub3ZhIGFvaTMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9Im1hcmt1cCJ9CmFvaTMgPC0gYygnZXllcycsJ21vdXRoJywnbmVjaycpCgojIE9yZ2FuaXplIHRoZSBkYXRhIGJ5IHRob3NlIEFPSXMgKGJ1dCBhZ2FpbiB3ZSBuZWVkIHBhcnRpY2lwYW50LWxldmVsIGZpcnN0KQphb2kzX2RhdGEgPC0gZnVsbGRhdGEgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQsIG1haW5ncm91cCwgaGVhcmluZywgYW9hc2wsIGFnZSwgZGlyZWN0aW9uLCBiZWxseTp1cHBlcmNoZXN0KSAlPiUKICBnYXRoZXIoYW9pLCBwZXJjZW50LCBiZWxseTp1cHBlcmNoZXN0KSAlPiUKICBncm91cF9ieShpZCwgZGlyZWN0aW9uLCBhb2kpICU+JQogIG11dGF0ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBmaWx0ZXIoYW9pICVpbiUgYW9pMykgJT4lCiAgc3ByZWFkKGFvaSwgcGVyY2VudCkKCiMgIyBMaW1pdCB0byBleWVzIG1vdXRoIG5lY2sKIyBiaWdfYW92X2FvaTMgPC0gYW9pM19kYXRhICU+JQojICAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgZXllczpuZWNrKSAlPiUKIyAgIGFvdihwZXJjZW50IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uICogYW9pLCBkYXRhID0gLikKIyAKIyBzdW1tYXJ5KGJpZ19hb3ZfYW9pMykKIyAKIyBiaWdfYW92X2FvaTNfbHNkIDwtIExTRC50ZXN0KGJpZ19hb3ZfYW9pMywgImFvaSIsIGdyb3VwID0gRkFMU0UpCiMgYmlnX2Fvdl9hb2kzX2xzZCRjb21wYXJpc29uCgphb2kzX2RhdGFfZ2F0aGVyIDwtIGFvaTNfZGF0YSAlPiUKICBnYXRoZXIoYW9pLCBwZXJjZW50LCBleWVzOm5lY2spICU+JQogIGZpbHRlcihpZCAhPSAiNiIpCgpiaWczX2FvdiA8LSBlekFOT1ZBKAogIGRhdGEgPSBhb2kzX2RhdGFfZ2F0aGVyLAogIGR2ID0gcGVyY2VudCwKICB3aWQgPSBpZCwKICB3aXRoaW4gPSAuKGRpcmVjdGlvbiwgYW9pKSwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KCnByaW50KGJpZzNfYW92WyJBTk9WQSJdKQpgYGAKIyMgTGVmdCBWcyBSaWdodApgYGB7ciBsZWZ0IHJpZ2h0IGFub3ZhLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSJtYXJrdXAifQphb2kzIDwtIGMoJ2xlZnQnLCdyaWdodCcpCgojIE9yZ2FuaXplIHRoZSBkYXRhIGJ5IHRob3NlIEFPSXMgKGJ1dCBhZ2FpbiB3ZSBuZWVkIHBhcnRpY2lwYW50LWxldmVsIGZpcnN0KQphb2lMUl9kYXRhIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGlkLCBtYWluZ3JvdXAsIGhlYXJpbmcsIGFvYXNsLCBhZ2UsIGRpcmVjdGlvbiwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ3JvdXBfYnkoaWQsIGFvaSkgJT4lCiAgbXV0YXRlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGZpbHRlcihhb2kgJWluJSBhb2kzKSAlPiUKICBzcHJlYWQoYW9pLCBwZXJjZW50KQoKYW9pTFJfZGF0YV9nYXRoZXIgPC0gYW9pTFJfZGF0YSAlPiUKICBnYXRoZXIoYW9pLCBwZXJjZW50LCBsZWZ0OnJpZ2h0KSAlPiUKICBmaWx0ZXIoaWQgIT0gIjYiKQoKYmlnTFJfYW92IDwtIGV6QU5PVkEoCiAgZGF0YSA9IGFvaUxSX2RhdGFfZ2F0aGVyLAogIGR2ID0gcGVyY2VudCwKICB3aWQgPSBpZCwKICB3aXRoaW4gPSBhb2ksCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCgpwcmludChiaWdMUl9hb3ZbIkFOT1ZBIl0pCmBgYAoKIyMgSW50ZXJhY3Rpb25zIFZpc3VhbGl6YXRpb24KU28gd2UgaGF2ZSBzaWduaWZpY2FudCBtYWluZ3JvdXA6YW9pIGFuZCBkaXJlY3Rpb246YW9pIGludGVyYWN0aW9ucy4gTGV0J3MgdHJ5IHRvIHZpc3VhbGl6ZSB3aGF0IGNhbiBiZSBkcml2aW5nIHRoZXNlLiBXZSBjYW4gZ28gYmFjayB0byB0aGUgU0VNIGNoYXJ0IGJ1dCBicmVhayBpdCBkb3duLi4uCgpGaXJzdCBhcmUgdGhlIG1haW5ncm91cDphb2kgY2hhcnRzICpUaGUgZXJyb3IgYmFycyBhcmUgbm90IDEwMCUgYWNjdXJhdGUsIEkgdG9vayBhIHF1aWNrLW4tZWFzeSB3YXkgYXJvdW5kKgoKYGBge3J9CmFvaTNfaW50ZXJhY3Rpb25zX21haW5ncm91cGFvaSA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChpZCwgcGFydGljaXBhbnQsIG1haW5ncm91cCwgZGlyZWN0aW9uLCBleWVzLCBtb3V0aCwgbmVjaykgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYyhleWVzLCBtb3V0aCwgbmVjaykpICU+JQogIGdyb3VwX2J5KGlkLCBtYWluZ3JvdXAsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGFvaSkgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHNkID0gc2QocGVyY2VudCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgY291bnQgPSBuKCkvMiwKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KGNvdW50KSkKIyBJIG5lZWQgdG8gZmlyc3QgY29sbGFwc2UgYWNyb3NzIHN0b3JpZXMgZm9yIGVhY2ggcGFydGljaXBhbnQuLi5oZXJlIEkgZGlkbid0LiBNdXN0IGZpeCBsYXRlci4KCmFvaTNfaW50ZXJhY3Rpb25zX21haW5ncm91cGFvaSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYW9pLCB5ID0gbWVhbiwgZmlsbCA9IG1haW5ncm91cCkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgd2lkdGggPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIk1haW5Hcm91cCAmIEFPSSBJbnRlcmFjdGlvbiAxIiwgc3VidGl0bGUgPSAiRXJyb3IgYmFycyByZXByZXNlbnQgU0UiLCB4ID0gIiIsIHkgPSAicGVyY2VudCBsb29raW5nIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KQoKYW9pM19pbnRlcmFjdGlvbnNfbWFpbmdyb3VwYW9pICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gYW9pKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW4tc2UsIHltYXggPSBtZWFuK3NlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCB3aWR0aCA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiTWFpbkdyb3VwICYgQU9JIEludGVyYWN0aW9uIDIiLCBzdWJ0aXRsZSA9ICJFcnJvciBiYXJzIHJlcHJlc2VudCBTRSIsIHggPSAiIiwgeSA9ICJwZXJjZW50IGxvb2tpbmciKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpCgoKYGBgCgpGaXJzdCBhcmUgdGhlIGRpcmVjdGlvbjphb2kgY2hhcnRzICpUaGUgZXJyb3IgYmFycyBhcmUgbm90IDEwMCUgYWNjdXJhdGUsIEkgdG9vayBhIHF1aWNrLW4tZWFzeSB3YXkgYXJvdW5kKgoKYGBge3J9CmFvaTNfaW50ZXJhY3Rpb25zX2RpcmVjdGlvbmFvaSA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChpZCwgcGFydGljaXBhbnQsIG1haW5ncm91cCwgZGlyZWN0aW9uLCBleWVzLCBtb3V0aCwgbmVjaykgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYyhleWVzLCBtb3V0aCwgbmVjaykpICU+JQogIGdyb3VwX2J5KGlkLCBtYWluZ3JvdXAsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBncm91cF9ieShkaXJlY3Rpb24sIGFvaSkgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHNkID0gc2QocGVyY2VudCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpCiMgSSBuZWVkIHRvIGZpcnN0IGNvbGxhcHNlIGFjcm9zcyBzdG9yaWVzIGZvciBlYWNoIHBhcnRpY2lwYW50Li4uaGVyZSBJIGRpZG4ndC4gTXVzdCBmaXggbGF0ZXIuCgphb2kzX2ludGVyYWN0aW9uc19kaXJlY3Rpb25hb2kgJT4lIAogIGdncGxvdChhZXMoeCA9IGFvaSwgeSA9IG1lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJNYWluR3JvdXAgJiBEaXJlY3Rpb24gSW50ZXJhY3Rpb24gMSIsIHN1YnRpdGxlID0gIkVycm9yIGJhcnMgcmVwcmVzZW50IFNFIiwgeCA9ICIiLCB5ID0gInBlcmNlbnQgbG9va2luZyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkKCmFvaTNfaW50ZXJhY3Rpb25zX2RpcmVjdGlvbmFvaSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGlyZWN0aW9uLCB5ID0gbWVhbiwgZmlsbCA9IGFvaSkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgd2lkdGggPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIk1haW5Hcm91cCAmIERpcmVjdGlvbiBJbnRlcmFjdGlvbiAyIiwgc3VidGl0bGUgPSAiRXJyb3IgYmFycyByZXByZXNlbnQgU0UiLCB4ID0gIiIsIHkgPSAicGVyY2VudCBsb29raW5nIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KQpgYGAKCgojIyBBbGwgdGhlIEFPSSBtZWFucwpMZXQncyBnZXQgdGFibGVzIG9mIG91ciBtZWFucyBoZXJlLCBpbiB2YXJpb3VzIGNvbmZpZ3VyYXRpb25zCgpgYGB7ciBhb2kgcmF3LCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KYW9pM19kYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoZXllcyA9IG1lYW4oZXllcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbW91dGggPSBtZWFuKG1vdXRoLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuZWNrID0gbWVhbihuZWNrLCBuYS5ybSA9IFRSVUUpKSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKHRvdGFsID0gc3VtKGV5ZXMsbW91dGgsbmVjaykpCgphb2kzX2RhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCkgJT4lCiAgc3VtbWFyaXNlKGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSkgICU+JQogIHJvd3dpc2UoKSAlPiUKICBtdXRhdGUodG90YWwgPSBzdW0oZXllcyxtb3V0aCxuZWNrKSkKCmFvaTNfZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSkgJT4lCiAgZ3JvdXBfYnkoZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoZXllcyA9IG1lYW4oZXllcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbW91dGggPSBtZWFuKG1vdXRoLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuZWNrID0gbWVhbihuZWNrLCBuYS5ybSA9IFRSVUUpKSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKHRvdGFsID0gc3VtKGV5ZXMsbW91dGgsbmVjaykpCgphb2kzX2RhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCkgJT4lCiAgc3VtbWFyaXNlKGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JSAKICBnYXRoZXIoYW9pLCBwZXJjZW50LCBleWVzOm5lY2spICU+JQogIGdyb3VwX2J5KGFvaSkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEV5ZXMKCjEuIEFOT1ZBIHdpdGggZmFjdG9ycyBNYWluR3JvdXAgJiBEaXJlY3Rpb24uCgpgYGB7ciBleWVzIGFub3ZhMSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQoKIyAjIGV5ZXMgQU5DT1ZBIDEKIyBleWVzX2FvdjEgPC0gYW92KGV5ZXMgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBhb2kzX2RhdGEpCiMgc3VtbWFyeShleWVzX2FvdjEpCiMgIyBleWVzX2xzZDEgPC0gTFNELnRlc3QoZXllc19hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIGV5ZXNfbHNkMSRjb21wYXJpc29uCgphb2kzX2RhdGEgPC0gZmlsdGVyKGFvaTNfZGF0YSwgaWQgIT0gIjYiKQplekFOT1ZBKAogIGRhdGEgPSBhb2kzX2RhdGEsCiAgZHYgPSBleWVzLAogIHdpZCA9IGlkLAogIHdpdGhpbiA9IGRpcmVjdGlvbiwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgoyLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBGb3J3YXJkIG9ubHkuCgpgYGB7ciBleWVzIGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojICMgZXllcyBBTk9WQSAyCiMgZXllc19hb3YyIDwtIGFvdihleWVzIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGFvaTNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCiMgc3VtbWFyeShleWVzX2FvdjIpCiMgIyBleWVzX2xzZDIgPC0gTFNELnRlc3QoZXllc19hb3YyLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIGV5ZXNfbHNkMiRjb21wYXJpc29uCgplekFOT1ZBKAogIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSwKICBkdiA9IGV5ZXMsCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGV5ZXMgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgIyBleWVzIEFOT1ZBIDMKIyBleWVzX2FvdjMgPC0gYW92KGV5ZXMgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCiMgc3VtbWFyeShleWVzX2FvdjMpCiMgIyBleWVzX2xzZDMgPC0gTFNELnRlc3QoZXllc19hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIGV5ZXNfbHNkMyRjb21wYXJpc29uCgplekFOT1ZBKAogIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIiksCiAgZHYgPSBleWVzLAogIHdpZCA9IGlkLAogIGJldHdlZW4gPSBtYWluZ3JvdXAsCiAgdHlwZSA9IDMKKVsiQU5PVkEiXQpgYGAKCiMjIE1vdXRoCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbW91dGggYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojICMgbW91dGggQU5DT1ZBIDEKIyBtb3V0aF9hb3YxIDwtIGFvdihtb3V0aCB+IG1haW5ncm91cCAqIGRpcmVjdGlvbiwgZGF0YSA9IGFvaTNfZGF0YSkKIyBzdW1tYXJ5KG1vdXRoX2FvdjEpCiMgbW91dGhfbHNkMSA8LSBMU0QudGVzdChtb3V0aF9hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBtb3V0aF9sc2QxJGNvbXBhcmlzb24KCmV6QU5PVkEoCiAgZGF0YSA9IGFvaTNfZGF0YSwKICBkdiA9IG1vdXRoLAogIHdpZCA9IGlkLAogIHdpdGhpbiA9IGRpcmVjdGlvbiwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgoyLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBGb3J3YXJkIG9ubHkuCgpgYGB7ciBtb3V0aCBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyAjIG1vdXRoIEFOT1ZBIDIKIyBtb3V0aF9hb3YyIDwtIGFvdihtb3V0aCB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQojIHN1bW1hcnkobW91dGhfYW92MikKIyAjIG1vdXRoX2xzZDIgPC0gTFNELnRlc3QobW91dGhfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgIyBtb3V0aF9sc2QyJGNvbXBhcmlzb24KZXpBTk9WQSgKICBkYXRhID0gZmlsdGVyKGFvaTNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIiksCiAgZHYgPSBtb3V0aCwKICB3aWQgPSBpZCwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgozLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgbW91dGggYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgIyBtb3V0aCBBTk9WQSAzCiMgbW91dGhfYW92MyA8LSBhb3YobW91dGggfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCiMgc3VtbWFyeShtb3V0aF9hb3YzKQojICMgbW91dGhfbHNkMyA8LSBMU0QudGVzdChtb3V0aF9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIG1vdXRoX2xzZDMkY29tcGFyaXNvbgplekFOT1ZBKAogIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIiksCiAgZHYgPSBtb3V0aCwKICB3aWQgPSBpZCwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgojIyBOZWNrCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbmVjayBhbm92YTEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KCiMgIyBuZWNrIEFOQ09WQSAxCiMgbmVja19hb3YxIDwtIGFvdihuZWNrIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pM19kYXRhKQojIHN1bW1hcnkobmVja19hb3YxKQojICMgbmVja19sc2QxIDwtIExTRC50ZXN0KG5lY2tfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgIyBuZWNrX2xzZDEkY29tcGFyaXNvbgoKZXpBTk9WQSgKICBkYXRhID0gYW9pM19kYXRhLAogIGR2ID0gbmVjaywKICB3aWQgPSBpZCwKICB3aXRoaW4gPSBkaXJlY3Rpb24sCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgbmVjayBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyAjIG5lY2sgQU5PVkEgMgojIG5lY2tfYW92MiA8LSBhb3YobmVjayB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQojIHN1bW1hcnkobmVja19hb3YyKQojICMgbmVja19sc2QyIDwtIExTRC50ZXN0KG5lY2tfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgIyBuZWNrX2xzZDIkY29tcGFyaXNvbgplekFOT1ZBKAogIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSwKICBkdiA9IG5lY2ssCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG5lY2sgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgIyBuZWNrIEFOT1ZBIDMKIyBuZWNrX2FvdjMgPC0gYW92KG5lY2sgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCiMgc3VtbWFyeShuZWNrX2FvdjMpCiMgIyBuZWNrX2xzZDMgPC0gTFNELnRlc3QobmVja19hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIG5lY2tfbHNkMyRjb21wYXJpc29uCmV6QU5PVkEoCiAgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSwKICBkdiA9IG5lY2ssCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKIyMgRmFjZUNoZXN0CgpXZSBvcmlnaW5hbGx5IGRlZmluZWQgRmFjZUNoZXN0IHN1Y2ggdGhhdAoKMS4gRmFjZSA9IGV5ZXMgKyBtb3V0aCArIGNoaW4KMS4gQ2hlc3QgPSB1cHBlcmNoZXN0ICsgbWlkY2hlc3QgKyBsb3dlcmNoZXN0CgpCVVQuIENoaW4gaXMgYWN0dWFsbHkgbmVjay4gSXQncyBub3QgZXZlbiBwYXJ0IG9mIHRoZSBmYWNlIGlmIHlvdSB0aGluayBhYm91dCBpdC4gU28gSSdtIHJlZGVmaW5pbmcgRmFjZUNoZXN0IGFzOgoKMS4gRmFjZSA9IGZvcmVoZWFkICsgZXllcyArIG1vdXRoCjEuIENoZXN0ID0gbmVjayArIHVwcGVyY2hlc3QgKyBtaWRjaGVzdCArIGxvd2VyY2hlc3QKClNvIGxldCdzIGRvIHRoaXMuIFRoZW4gc2VlIHdoYXQncyBoYXBwZW5pbmcgYWNyb3NzIGdyb3VwcyBmb3IgRmFjZUNoZXN0LgoKYGBge3IgY2FsY3VsYXRlIGZhY2VjaGVzdCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIENhbGN1bGF0ZSBmYWNlLCBjaGVzdCwgYW5kIGZhY2VjaGVzdCAtIGFuZCBtb3V0aGV5ZSB0b28KZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZShmYWNlID0gc3VtKGZvcmVoZWFkLCBleWVzLCBtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgY2hlc3QgPSBzdW0obmVjaywgdXBwZXJjaGVzdCwgbWlkY2hlc3QsIGxvd2VyY2hlc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGZhY2VjaGVzdCA9IChmYWNlIC0gY2hlc3QpLyhmYWNlICsgY2hlc3QpLAogICAgICAgICBtb3V0aGV5ZSA9IChtb3V0aCAtIGV5ZXMpLyhtb3V0aCArIGV5ZXMpKQoKIyBmdWxsZGF0YSAlPiUgCiMgICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgYyhmYWNlY2hlc3Rfb2xkLCBmYWNlY2hlc3QpKSAlPiUKIyAgIGdncGxvdChhZXMoeCA9IG1haW5ncm91cCwgeSA9IHZhbHVlLCBmaWxsID0gZGlyZWN0aW9uKSkgKyBnZW9tX2JveHBsb3QoKSArIGZhY2V0X3dyYXAoIm1ldHJpYyIpCmBgYAoKQ29vbC4gTmV4dCB3ZSdsbCBkbyBlcnJvciBiYXIgY2hhcnRzIHVzaW5nIHRoZSBuZXcgRmFjZUNoZXN0IGFjcm9zcyBncm91cHMuIAoKYGBge3IgZmFjZWNoZXN0IGJhcnMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmZhY2VjaGVzdF9pbmZvIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24sIHBhcnRpY2lwYW50KSAlPiUKICBzdW1tYXJpc2UoZmFjZWNoZXN0ID0gbWVhbihmYWNlY2hlc3QsIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oZmFjZWNoZXN0KSwKICAgICAgICAgICAgc2QgPSBzZChmYWNlY2hlc3QpLAogICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQobikpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUobWFpbmdyb3VwID0gY2FzZV93aGVuKAogICAgbWFpbmdyb3VwID09ICJEZWFmRWFybHkiIH4gIkRlYWYgRWFybHkiLAogICAgbWFpbmdyb3VwID09ICJEZWFmTGF0ZSIgfiAiRGVhZiBMYXRlIiwKICAgIG1haW5ncm91cCA9PSAiSGVhcmluZ0xhdGUiIH4gIkhlYXJpbmcgTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdOb3ZpY2UiIH4gIkhlYXJpbmcgTm92aWNlIgogICAgKSkKCmdncGxvdChmYWNlY2hlc3RfaW5mbywgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gZGlyZWN0aW9uLCBjb2xvciA9IGRpcmVjdGlvbikpICsKICBnZW9tX3BvaW50KHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNSksIHNpemUgPSAyKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC41KSwgd2lkdGggPSAwLjMsIHNpemUgPSAxKSArCiAgbGFicyh0aXRsZSA9ICJGYWNlLUNoZXN0IFJhdGlvIiwgeCA9ICIiLCB5ID0gImZhY2UtY2hlc3QgcmF0aW8iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsMSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZG90dGVkIikgKwogIHRoZW1lX2J3KCkKYGBgCgpOb3cgbGV0J3MgZG8gdGhlIEFOT1ZBcy4gQWxzbyBza2lwcGluZyBMU0RzIGhlcmUuIAoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGZhY2VjaGVzdCBhbm92YSAxLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCcsIG1lc3NhZ2U9RkFMU0V9CiMgQ3JlYXRlIHRoZSBwYXJ0aWNpcGFudC1sZXZlbCBkYiAobGV0J3MgYWxzbyBwb3AgbW91dGhleWUgaW4gdGhpcyB0b28pCmZjX2RhdGEgPC0gZnVsbGRhdGEgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQsIG1haW5ncm91cCwgaGVhcmluZywgYW9hc2wsIGFnZSwgZGlyZWN0aW9uLCBmYWNlY2hlc3QsIG1vdXRoZXllKSAlPiUKICBncm91cF9ieShpZCwgZGlyZWN0aW9uKSAlPiUKICBtdXRhdGUoZmFjZWNoZXN0ID0gbWVhbihmYWNlY2hlc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIG1vdXRoZXllID0gbWVhbihtb3V0aGV5ZSwgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZmlsdGVyKGlkICE9ICI2IikKCiMgIyBmYWNlY2hlc3QgQU5DT1ZBIDEKIyBmYWNlY2hlc3RfYW92MSA8LSBhb3YoZmFjZWNoZXN0IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gZmNfZGF0YSkKIyBzdW1tYXJ5KGZhY2VjaGVzdF9hb3YxKQojICMgZmFjZWNoZXN0X2xzZDEgPC0gTFNELnRlc3QoZmFjZWNoZXN0X2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojICMgZmFjZWNoZXN0X2xzZDEkY29tcGFyaXNvbgoKZXpBTk9WQSgKICBkYXRhID0gZmNfZGF0YSwKICBkdiA9IGZhY2VjaGVzdCwKICB3aWQgPSBpZCwKICB3aXRoaW4gPSBkaXJlY3Rpb24sCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgZmFjZWNoZXN0IGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojICMgZmFjZWNoZXN0IEFOT1ZBIDIKIyBmYWNlY2hlc3RfYW92MiA8LSBhb3YoZmFjZWNoZXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQojIHN1bW1hcnkoZmFjZWNoZXN0X2FvdjIpCiMgIyBmYWNlY2hlc3RfbHNkMiA8LSBMU0QudGVzdChmYWNlY2hlc3RfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgIyBmYWNlY2hlc3RfbHNkMiRjb21wYXJpc29uCgplekFOT1ZBKAogIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIiksCiAgZHYgPSBmYWNlY2hlc3QsCiAgd2lkID0gaWQsCiAgYmV0d2VlbiA9IG1haW5ncm91cCwKICB0eXBlID0gMwopWyJBTk9WQSJdCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGZhY2VjaGVzdCBhbm92YTMsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyAjIGZhY2VjaGVzdCBBTk9WQSAzCiMgZmFjZWNoZXN0X2FvdjMgPC0gYW92KGZhY2VjaGVzdCB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihmY19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCiMgc3VtbWFyeShmYWNlY2hlc3RfYW92MykKIyAjIGZhY2VjaGVzdF9sc2QzIDwtIExTRC50ZXN0KGZhY2VjaGVzdF9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyAjIGZhY2VjaGVzdF9sc2QzJGNvbXBhcmlzb24KZXpBTk9WQSgKICBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSwKICBkdiA9IGZhY2VjaGVzdCwKICB3aWQgPSBpZCwKICBiZXR3ZWVuID0gbWFpbmdyb3VwLAogIHR5cGUgPSAzCilbIkFOT1ZBIl0KYGBgCgojIEV5ZSBHYXplICYgUGVyZm9ybWFuY2UgQ29ycmVsYXRpb25zCgpOZXh0IHdlJ3JlIGdvaW5nIHRvIGNvcnJlbGF0ZSBvdXIgZXllIGdhemUgbWV0cmljcyAoRXllLCBNb3V0aCwgTmVjaywgYW5kIEZhY2VDaGVzdCkgd2l0aCBsZXhpY2FsIHJlY2FsbCBhbmQgZ2lzdC4gT2theSEgQnV0IHJlbWVtYmVyIHdlIGhhdmUgYSBzbGlnaHRseSBzbWFsbGVyIGRhdGFzZXQgaGVyZSBiZWNhdXNlIHdlJ3ZlIGV4Y2x1ZGVkIHNvbWUgcGFydGljaXBhbnRzIGZvciBoYXZpbmcgYmFkIGV5ZSBkYXRhIChidXQgdGhleSBoYWQgdmFsaWQgYmVoYXZpb3JhbCBkYXRhIHNvIHdlIGtlcHQgdGhlbSBpbiB0aGUgQW9BLVBlcmZvcm1hbmNlIGNvcnJlbGF0aW9ucyBhYm92ZSkuIAoKKipXZSBhbHNvIHJlbW92ZWQgZ2lzdF9mb3J3YXJkIGNvbHVtbi4qKgoKYGBge3IgcmVwYWNrYWdlIGRhdGEgZm9yIGNvcnJlbGF0aW9ucyBhZ2Fpbn0KZXllcGVyZiA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwLCBoZWFyaW5nLCBkaXJlY3Rpb24sIGFvYXNsLCBzaWdueXJzLCBhY2MsIGdpc3QsIGV5ZXMsIG1vdXRoLCBuZWNrLCBmYWNlY2hlc3QpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgbXV0YXRlKGdpc3QgPSBtZWFuKGdpc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGxleCA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGZhY2VjaGVzdCA9IG1lYW4oZmFjZWNoZXN0LCBuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGhlYXJpbmcsIGRpcmVjdGlvbiwgYW9hc2wsIHNpZ255cnMsIGdpc3QsIGxleCwgZXllcywgbW91dGgsIG5lY2ssIGZhY2VjaGVzdCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgZ2lzdDpmYWNlY2hlc3QpICU+JQogIHVuaXRlKG1ldHJpY3ZhbHVlLCBjKG1ldHJpYywgZGlyZWN0aW9uKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQobWV0cmljdmFsdWUsIHZhbHVlKSAlPiUKICBzZWxlY3QoLXBhcnRpY2lwYW50LCAtbWFpbmdyb3VwKSAlPiUKICBzZWxlY3QoaGVhcmluZywgYW9hc2wsIHNpZ255cnMsIGdpc3RfcmV2ZXJzZWQsIGxleF9mb3J3YXJkLCBsZXhfcmV2ZXJzZWQsIGV5ZXNfZm9yd2FyZCwgZXllc19yZXZlcnNlZCwKICAgICAgICAgbW91dGhfZm9yd2FyZCwgbW91dGhfcmV2ZXJzZWQsIG5lY2tfZm9yd2FyZCwgbmVja19yZXZlcnNlZCwgZmFjZWNoZXN0X2ZvcndhcmQsIGZhY2VjaGVzdF9yZXZlcnNlZCkKCmV5ZXBlcmZfZGVhZiA8LSBleWVwZXJmICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiRGVhZiIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmV5ZXBlcmZfaGVhcmluZyA8LSBleWVwZXJmICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiSGVhcmluZyIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmV5ZXBlcmZfYWxsIDwtIGV5ZXBlcmYgJT4lIHNlbGVjdCgtaGVhcmluZykKCgojIENvcnJlbGF0aW9ucyBmb3IgRGVhZgpwcmludCgiREVBRiBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9kZWFmKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfZGVhZikpJHIKcHJpbnQoIkRFQUYgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfZGVhZikpJFAKY2F0KHBhc3RlKCIiLCJcbiIsIiIpKQoKIyBDb3JyZWxhdGlvbnMgZm9yIEhlYXJpbmcKcHJpbnQoIkhFQVJJTkcgQ29ycmVsYXRpb25zIC0gUGVhcnNvbidzIHIiKQojY29yc3RhcnNsKGxleGdpc3RfaGVhcmluZykKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChleWVwZXJmX2hlYXJpbmcpKSRyCnByaW50KCJIRUFSSU5HIENvcnJlbGF0aW9ucyAtIFAtdmFsdWVzIikKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChleWVwZXJmX2hlYXJpbmcpKSRQCmNhdChwYXN0ZSgiIiwiXG4iLCIiKSkKCiMgQ29ycmVsYXRpb25zIGZvciBBbGwKcHJpbnQoIkFMTCBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9hbGwpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgoZXllcGVyZl9hbGwpKSRyCnByaW50KCJBTEwgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfYWxsKSkkUAoKYGBgCgpJJ20gYWxzbyBpbmNsdWRpbmcgbmljZWx5IGZvcm1hdHRlZCB0YWJsZXMgd2l0aCAqKiogaW5kaWNhdG9ycyBvZiBzaWduaWZpY2FuY2UgZm9yIHF1aWNrIHJlZmVyZW5jaW5nLiBPcmRlcjogRGVhZiwgSGVhcmluZywgQWxsLiAKCmBgYHtyIHByZXR0eSBjb3JyZWxhdGlvbnMgZm9yIGV5ZXBlcmYsIHJvd3MucHJpbnQgPSAxNX0KY29yc3RhcnNsKGV5ZXBlcmZfZGVhZikKY29yc3RhcnNsKGV5ZXBlcmZfaGVhcmluZykKY29yc3RhcnNsKGV5ZXBlcmZfYWxsKQpgYGAKCkFuZCB0aGUgY29ycmVsYXRpb24gdGFibGUuCgpgYGB7ciBleWVwZXJmIGNvcnJlbGF0aW9uIGNoYXJ0cywgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3BhaXJzKGV5ZXBlcmYsIGNvbHVtbnMgPSBjKDI6MTMpLCBhZXMoY29sb3IgPSBoZWFyaW5nKSkKYGBgCgojIEhlYXQgTWFwcwpBbmQgZmluYWxseSwgd2UncmUgZ29pbmcgdG8gZG8gaGVhdCBtYXBzLiAKYGBge3IgaGVhdCBtYXB9CmV5ZWdhemVfaGVhdCA8LSBmdWxsZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQ6ZGlyZWN0aW9uLCBiZWxseSwgbG93ZXJjaGVzdCwgbWlkY2hlc3QsIHVwcGVyY2hlc3QsIG5lY2ssIG1vdXRoLCBleWVzLCBmb3JlaGVhZCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6Zm9yZWhlYWQpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm09VFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCxkaXJlY3Rpb24sYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm09VFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGFvaSkpICU+JQogIG11dGF0ZShhb2kgPSBmYWN0b3IoYW9pLGxldmVscz1jKCJiZWxseSIsImxvd2VyY2hlc3QiLCJtaWRjaGVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVwcGVyY2hlc3QiLCJuZWNrIiwibW91dGgiLCJleWVzIiwiZm9yZWhlYWQiKSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUobWFpbmdyb3VwID0gY2FzZV93aGVuKAogICAgbWFpbmdyb3VwID09ICJEZWFmRWFybHkiIH4gIkRlYWYgRWFybHkiLAogICAgbWFpbmdyb3VwID09ICJEZWFmTGF0ZSIgfiAiRGVhZiBMYXRlIiwKICAgIG1haW5ncm91cCA9PSAiSGVhcmluZ0xhdGUiIH4gIkhlYXJpbmcgTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdOb3ZpY2UiIH4gIkhlYXJpbmcgTm92aWNlIgogICAgKSkKCmV5ZWdhemVfaGVhdF9hbGwgPC0gZnVsbGRhdGEgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGlkOmRpcmVjdGlvbiwgYmVsbHksIGxvd2VyY2hlc3QsIG1pZGNoZXN0LCB1cHBlcmNoZXN0LCBuZWNrLCBtb3V0aCwgZXllcywgZm9yZWhlYWQpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OmZvcmVoZWFkKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAscGFydGljaXBhbnQsZGlyZWN0aW9uLGFvaSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLGRpcmVjdGlvbixhb2kpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm09VFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCxhb2kpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm09VFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGFvaSkpICU+JQogIG11dGF0ZShhb2kgPSBmYWN0b3IoYW9pLGxldmVscz1jKCJiZWxseSIsImxvd2VyY2hlc3QiLCJtaWRjaGVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVwcGVyY2hlc3QiLCJuZWNrIiwibW91dGgiLCJleWVzIiwiZm9yZWhlYWQiKSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUobWFpbmdyb3VwID0gY2FzZV93aGVuKAogICAgbWFpbmdyb3VwID09ICJEZWFmRWFybHkiIH4gIkRlYWYgRWFybHkiLAogICAgbWFpbmdyb3VwID09ICJEZWFmTGF0ZSIgfiAiRGVhZiBMYXRlIiwKICAgIG1haW5ncm91cCA9PSAiSGVhcmluZ0xhdGUiIH4gIkhlYXJpbmcgTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdOb3ZpY2UiIH4gIkhlYXJpbmcgTm92aWNlIgogICAgKSkKCmdncGxvdChleWVnYXplX2hlYXQsIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gYW9pKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbD1wZXJjZW50KSxjb2xvcj0ibGlnaHRncmF5IixuYS5ybT1UUlVFKSArIAogIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAidmlyaWRpcyIsIGRpcmVjdGlvbj0tMSwgbGltaXRzID0gYygwLC43MSksIGxhYmVscyA9IHBlcmNlbnQsIG5hbWUgPSAibG9va2luZyB0aW1lIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT0zMCxoanVzdD0xKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiaXRhbGljIiksIAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIndoaXRlIiwgZmlsbCA9ICJ3aGl0ZSIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAid2hpdGUiKSkgKwogIGZhY2V0X2dyaWQoLiB+IGRpcmVjdGlvbikgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCwgYnkgRGlyZWN0aW9uIikgKyAKICBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZD1jKDAsMCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZCA9IGMoMCwwKSkKCgpnZ3Bsb3QoZXllZ2F6ZV9oZWF0X2FsbCwgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBhb2kpKSArCiAgZ2VvbV90aWxlKGFlcyhmaWxsPXBlcmNlbnQpLGNvbG9yPSJsaWdodGdyYXkiLG5hLnJtPVRSVUUpICsgCiAgc2NhbGVfZmlsbF92aXJpZGlzKG9wdGlvbiA9ICJ2aXJpZGlzIiwgZGlyZWN0aW9uPS0xLCBsaW1pdHMgPSBjKDAsLjcxKSwgbGFiZWxzID0gcGVyY2VudCwgbmFtZSA9ICJsb29raW5nIHRpbWUiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTMwLGhqdXN0PTEpLCAKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gIndoaXRlIikpICsKICB5bGFiKCIiKSArIHhsYWIoIiIpICsgZ2d0aXRsZSgiRXllIEdhemUgSGVhdCBNYXAgKERpcmVjdGlvbiBDb2xsYXBzZWQpIikgKwogIHNjYWxlX3lfZGlzY3JldGUoZXhwYW5kPWMoMCwwKSkgKwogIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kID0gYygwLDApKQoKYGBgCgojIFN1bW1hcnkKCkJlbG93IGFyZSB0aGUgcC12YWx1ZXMgZnJvbSB0aGUgQU5PVkFzIHdpdGggNCBNYWluR3JvdXBzLiBJIG5ldmVyIGluY2x1ZGVkIEFnZSBhcyBhIGNvdmFyaWF0ZSBiZWNhdXNlIGl0IG5ldmVyIGltcHJvdmVkIHRoZSBtb2RlbC4gSSBpbmNsdWRlZCBhbGwgQU5PVkFzIGZvciBHaXN0IGFuZCBMZXggUmVjYWxsLCBhbmQgQU5PVkFzIGZvciBhbnkgZXllIEFPSSBvciByYXRpbyB3YXMgaW5jbHVkZWQgb25seSBpZiBlaXRoZXIgbWFpbmdyb3VwIG9yIGRpcmVjdGlvbiB3YXMgc2lnbmlmaWNhbnQuIERlYWZlYXJseS1EZWFmbGF0ZSBzaG93cyB0aGUgTFNEIHAtdmFsdWUgZm9yIHRoYXQgY29tcGFyaXNvbi4KYGBge3IgcmVzdWx0czEsIHJvd3MucHJpbnQgPSAyMH0KcmVzdWx0czEgPC0gc3RydWN0dXJlKGxpc3QobW9kZWwgPSBjKCJnaXN0LW1haW5ncm91cC1ib3RoIiwgImdpc3QtbWFpbmdyb3VwLWZ3IiwgCiJnaXN0LW1haW5ncm91cC1ydiIsICJsZXhyZWNhbGwtbWFpbmdyb3VwLWJvdGgiLCAibGV4cmVjYWxsLW1haW5ncm91cC1mdyIsIAoibGV4cmVjYWxsLW1haW5ncm91cC1ydiIsICJtb3V0aC1tYWluZ3JvdXAtYm90aCIsICJ1cHBlcmNoZXN0LW1haW5ncm91cC1ib3RoIiwgCiJ1cHBlcmNoZXN0LW1haW5ncm91cC1ydiIsICJmYWNlY2hlc3QtbWFpbmdyb3VwLWJvdGgiLCAibW91dGhleWUtbWFpbmdyb3VwLWJvdGgiCiksIG1haW5ncm91cCA9IGMoMCwgMCwgMC4wMSwgMCwgMC4wNCwgMC4wMiwgMC4wNiwgMCwgMC4wMSwgMC4xLCAKMC4wNSksIGRpcmVjdGlvbiA9IGMoMCwgTkEsIE5BLCAwLCBOQSwgTkEsIDAuMDYsIDAuMTYsIE5BLCAwLjA3LCAKMC40OCksIGBkZWFmZWFybHktZGVhZmxhdGVgID0gYygwLjEsIDAuNjksIDAuMDIsIDAuMTEsIDAuOTUsIAowLjA2LCAwLjM4LCAwLjk0LCAwLjUyLCAwLjA4LCAwLjY4KSksIC5OYW1lcyA9IGMoIm1vZGVsIiwgIm1haW5ncm91cCIsIAoiZGlyZWN0aW9uIiwgImRlYWZlYXJseS1kZWFmbGF0ZSIpLCBjbGFzcyA9IGMoInRibF9kZiIsICJ0YmwiLCAKImRhdGEuZnJhbWUiKSwgcm93Lm5hbWVzID0gYyhOQSwgLTExTCkpCgpyZXN1bHRzMQpgYGAKCkFuZCBiZWxvdyBhcmUgdGhlIHAtdmFsdWVzIGZyb20gdGhlIEFOQ09WQXMgd2l0aCBIZWFyaW5nICYgQW9BU0wuIEkgaW5jbHVkZWQgYWxsIEFOQ09WQXMgZm9yIEdpc3QgYW5kIExleCBSZWNhbGwsIGFuZCBBTkNPVkFzIGZvciBhbnkgZXllIEFPSSBvciByYXRpbyB3YXMgaW5jbHVkZWQgb25seSBpZiBhbnkgbWFpbiBmYWN0b3Igd2FzIHNpZ25pZmljYW50LiBMU0QgY29tcGFyaXNvbnMgYXJlIG5vdCBuZWVkZWQgYmVjYXVzZSB0aGVyZSdzIG9ubHkgMiBsZXZlbHMgaW4gZWFjaCBncm91cCEKCmBgYHtyIHJlc3VsdHMyLCByb3dzLnByaW50ID0gMjV9CnJlc3VsdHMyIDwtIHN0cnVjdHVyZShsaXN0KG1vZGVsID0gYygiZ2lzdC1ib3RoIiwgImdpc3QtZnciLCAiZ2lzdC1ydiIsICJsZXgtYm90aCIsIAoibGV4LWZ3IiwgImxleC1ydiIsICJmb3JlaGVhZC1mdyIsICJtb3V0aC1ib3RoIiwgIm1vdXRoLXJ2IiwgCiJ1cHBlcmNoZXN0LWJvdGgiLCAidXBwZXJjaGVzdC1ydiIsICJmYWNlY2hlc3QtYm90aCIsICJtb3V0aGV5ZS1ib3RoIgopLCBoZWFyaW5nID0gYygwLCAwLjAwLCAwLjAxLCAwLjAxLCAwLjIyLCAwLjAzLCAwLjA2LCAwLjAxLCAKMC4wNCwgMC4wMSwgMC4wMSwgMC4zNSwgMC4wNyksIGRpcmVjdGlvbiA9IGMoMCwgTkEsIE5BLCAwLCBOQSwgCk5BLCBOQSwgMC4wNSwgTkEsIDAuMjEsIE5BLCAwLjA1LCAwLjUyKSwgYW9hc2wgPSBjKDAuMjIsIDAuNzcsIAowLjE5LCAwLjU2LCAwLjU4LCAwLjI1LCAwLjA4LCAwLjA2LCAwLjEyLCAwLjY4LCAwLjk1LCAwLjEyLCAwLjQ0CiksIGFnZSA9IGMoMC4wOCwgMC4wMSwgMC44NiwgMC4wOSwgMC4wMiwgMC43LCAwLjY4LCAwLjI4LCAwLjUsIAowLjAyLCAwLjA4LCAwLjAwLCAwLjIxKSksIC5OYW1lcyA9IGMoIm1vZGVsIiwgImhlYXJpbmciLCAiZGlyZWN0aW9uIiwgCiJhb2FzbCIsICJhZ2UiKSwgY2xhc3MgPSBjKCJ0YmxfZGYiLCAidGJsIiwgImRhdGEuZnJhbWUiKSwgcm93Lm5hbWVzID0gYyhOQSwgCi0xM0wpKQpyZXN1bHRzMgpgYGAKCkZpbmFsbHksIHRoZSBjb3JyZWxhdGlvbnMgZm9yIERlYWYgYW5kIEhlYXJpbmcgc2VwYXJhdGVseSBhcmUgbm90IHNpZ25pZmljYW50LiBCdXQgdGhlcmUgYXJlIHNpZ25pZmljYW50IGNvcnJlbGF0aW9ucyBhY3Jvc3MgYWxsIHBhcnRpY2lwYW50cy4gSSB3b3JyeSBpdCBpcyBjYXVzZWQgYnkgSGVhcmluZ05vdmljZSwgdGhvdWdoLi4uCgpgYGB7ciBjb3JyZWxhdGlvbiB0YWJsZX0KcmVzdWx0czMgPC0gdHJpYmJsZSgKICB+IG1ldHJpYywgfiBBb0FTTGNvcnJlbGF0aW9uUnZhbHVlLCB+IFB2YWx1ZSwKICAiZ2lzdC1mdyIsIC0wLjMyLCAwLjAxOSwKICAiZ2lzdC1ydiIsIC0wLjM5LCAwLjAwNCwKICAibGV4LWZ3IiwgLTAuMDgsIDAuNTY3LAogICJsZXgtcnYiLCAtMC4zNCwgMC4wMTQKKQpyZXN1bHRzMwpgYGAKCiMgVGVybmFyeSBQbG90cwoKTGV0J3MgbWFrZSB0cmlhbmdsZSBwbG90cy4gIldoYXQ/IiB5b3Ugc2F5LiBSZWFkIG9uLiAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShnZ3Rlcm4pCmZ1bGxkYXRhICU+JSAKICBnZ3Rlcm4oYWVzKHggPSBleWVzLCB5ID0gbW91dGgsIHogPSBuZWNrKSkgKyBmYWNldF9ncmlkKGRpcmVjdGlvbiB+IG1haW5ncm91cCkgKyBzdGF0X2RlbnNpdHlfdGVybihnZW9tPSdwb2x5Z29uJywgYWVzKGZpbGw9Li5sZXZlbC4uKSwgYmlucz00KSArIGdlb21fcG9pbnQoY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuNSkgKyB0aGVtZV9idygpCgpmdWxsZGF0YSAlPiUgCiAgZ2d0ZXJuKGFlcyh4ID0gZXllcywgeSA9IG1vdXRoLCB6ID0gbmVjaykpICsgZmFjZXRfZ3JpZChkaXJlY3Rpb24gfiBtYWluZ3JvdXApICsgZ2VvbV9jb25maWRlbmNlX3Rlcm4oYnJlYWtzID0gYyguNSksIGNvbG9yID0gInJlZCIpICsgZ2VvbV9wb2ludCgpICsgdGhlbWVfYncoKQpgYGAKCiMgUmFpbidzIE5vdGVzCkFib3V0IEFkdWx0czoKCi1JIHRoaW5rIEkgd2FudCB0byB3cml0ZSBpdCB1cCBhcyBhbiBBTkNPVkEsIHdpdGggZGlyZWN0aW9uIGluY2x1ZGVkLiAgQW5kIExTRCBjb21wYXJpc29ucyBpbnN0ZWFkIG9mIFR1a2V5LiAgKEkgd2lsbCBkbyBteSBvd24gY29ycmVjdGlvbnMpCi1Zb3Ugb2Z0ZW4gaGF2ZSBvbmUgbGluZXJzIHN1bW1hcml6aW5nIHJlc3VsdHMsIGluIGFsbCB0YWJzLCB0aG9zZSBhcmUgbmljZSwga2VlcCB0aGVtIGNvbWluZy4KLShJZiB5b3UgaGF2ZSByZWFzb25zIHRvIHByZXNlbnQgYW55dGhpbmcgb3RoZXIgdGhhbiB0aGUgQU5DT1ZBLCBwdXQgdGhhdCBpbiB5b3VyIHJlc3VsdHMgdGFiKQogCkkgdGhpbmsgaWYgd2UgZG8gaXQgdGhpcyB3YXkgdGhlbiB3ZSBnZXQgYSByZWFsbHkgaW1wb3J0YW50IHN0b3J5IHRvIHRlbGw6ICBUaGF0IHRoZSAqY3JpdGljYWwqIEFvQSBjdXRvZmYgaXMgYmVsb3cgNCB2cyBhYm92ZSA0IHllYXJzIG9mIGFnZSAodHdvIGdyb3VwcyAwLTQgdnMgNC0xMykuICBUaGlzIHN1Z2dlc3QgZWFybHkgQVNMIGlzIGltcG9ydGFudC4gIAoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyBHaXN0IGFzIGJpbm9taWFsIGxvZ2l0LWxpbmsgZnVuY3Rpb24gbW9kZWwKZ2lzdF9nbG1tIDwtIGdsbWVyKGdpc3QgfiBkaXJlY3Rpb24gKiBtYWluZ3JvdXAgKyAoMXxpZCkgKyAoMXxzdG9yeSksIGRhdGEgPSBmdWxsZGF0YSwgZmFtaWx5PWJpbm9taWFsIChsaW5rPSJsb2dpdCIpKQpzdW1tYXJ5KGdpc3RfZ2xtbSkKYGBgCg==